A framework-agnostic Kotlin / JVM and Java client for the OpenHolidays API, providing easy access to public holidays and school holidays for countries worldwide.
Works seamlessly with Spring Boot, Ktor, and any other JVM framework.
Artifacts are published per flavor so you only pull the dependencies you need.
io.github.breezko:open-holiday-kotlin-core– interfaces + models (no HTTP stack)io.github.breezko:open-holiday-kotlin-ktor– Ktor-powered client (depends oncore)io.github.breezko:open-holiday-kotlin-spring– Spring WebClient implementation (depends oncore)
<!-- Core -->
<dependency>
<groupId>io.github.breezko</groupId>
<artifactId>open-holiday-kotlin-core</artifactId>
<version>${openHoliday.version}</version>
</dependency>
<!-- Ktor client -->
<dependency>
<groupId>io.github.breezko</groupId>
<artifactId>open-holiday-kotlin-ktor</artifactId>
<version>${openHoliday.version}</version>
</dependency>
<!-- Spring WebClient -->
<dependency>
<groupId>io.github.breezko</groupId>
<artifactId>open-holiday-kotlin-spring</artifactId>
<version>${openHoliday.version}</version>
</dependency>implementation("io.github.breezko:open-holiday-kotlin-core:<version>")
implementation("io.github.breezko:open-holiday-kotlin-ktor:<version>") // Ktor flavor
implementation("io.github.breezko:open-holiday-kotlin-spring:<version>") // Spring flavorThis library follows a framework-agnostic architecture:
- Core API: Plain Kotlin interfaces and data classes with no framework dependencies
- Multiple Implementations: Built-in support for Ktor and Spring WebClient
- Easy Integration: Works with any Kotlin/JVM project, including Spring Boot, Ktor, Quarkus, Micronaut, etc.
- Extensible: Create your own implementation with OkHttp, HttpClient, or any HTTP library
- Framework-agnostic core - No forced dependencies
- Kotlin Coroutines - All methods are suspend functions
- Type-safe API - Leverages Kotlin's type system
- Multiple implementations - Choose between Ktor or Spring WebClient
- Comprehensive coverage - All OpenHolidays API endpoints supported
- Well documented - KDoc comments on all public APIs
- Localization support - Query data in multiple languages
Add the dependency to your build.gradle.kts:
dependencies {
implementation("io.github.breezko:open-holiday-kotlin-core:1.3.0")
// Pick one (or both) concrete implementations:
implementation("io.github.breezko:open-holiday-kotlin-ktor:1.3.0")
// or
implementation("io.github.breezko:open-holiday-kotlin-spring:1.3.0")
}Note: The library uses java.time.LocalDate from the JDK, so there are no additional date/time dependencies required. This makes it compatible with all JVM frameworks including Spring, Ktor, Micronaut, Quarkus, etc.
Sample implementations at samples-directory.
import org.openholidays.HolidaysClient
import org.openholidays.ktor.KtorHolidaysClient
import java.time.LocalDate
val client: HolidaysClient = KtorHolidaysClient.create()
try {
val holidays = client.getPublicHolidays(
countryIsoCode = "US",
validFrom = LocalDate.of(2025, 1, 1),
validTo = LocalDate.of(2025, 12, 31),
languageIsoCode = "EN"
)
holidays.forEach { holiday ->
println("${holiday.startDate}: ${holiday.name.first().text}")
}
} finally {
(client as? AutoCloseable)?.close()
}import org.openholidays.HolidaysClient
import org.openholidays.spring.SpringWebClientHolidaysClient
// Standalone usage
val client: HolidaysClient = SpringWebClientHolidaysClient.create()
// Or with Spring Boot dependency injection:
@Configuration
class HolidaysConfig {
@Bean
fun holidaysClient(webClientBuilder: WebClient.Builder): HolidaysClient {
return SpringWebClientHolidaysClient.create(
webClientBuilder = webClientBuilder
)
}
}
@Service
class HolidayService(private val holidaysClient: HolidaysClient) {
suspend fun getHolidays(country: String): List<Holiday> {
return holidaysClient.getPublicHolidays(
countryIsoCode = country,
validFrom = LocalDate.of(2025, 1, 1),
validTo = LocalDate.of(2025, 12, 31)
)
}
}The HolidaysClient interface provides the following methods:
getCountries()- List all supported countriesgetLanguages()- List all supported languagesgetSubdivisions()- Get subdivisions (states/provinces) for a countrygetGroups()- Get groups (school types) for a country
getPublicHolidays()- Get public holidays for a country in a date rangegetPublicHolidaysByDate()- Get all public holidays on a specific dategetPublicHolidayStatistics()- Get statistics about public holiday data
getSchoolHolidays()- Get school holidays for a country in a date rangegetSchoolHolidaysByDate()- Get all school holidays on a specific dategetSchoolHolidayStatistics()- Get statistics about school holiday data
All data models are plain Kotlin data classes in the org.openholidays.model package:
data class Holiday(
val id: String,
val name: List<LocalizedText>,
val startDate: LocalDate,
val endDate: LocalDate,
val type: HolidayType,
val nationwide: Boolean,
// ... more fields
)
data class Country(
val isoCode: String,
val name: List<LocalizedText>,
val officialLanguages: List<String>
)val client = KtorHolidaysClient.create {
// Custom Ktor configuration
install(HttpTimeout) {
requestTimeoutMillis = 30000
}
}try {
val holidays = client.getPublicHolidays(...)
} catch (e: HolidaysApiException) {
println("API Error: HTTP ${e.statusCode}")
e.problem?.let { problem ->
println("Title: ${problem.title}")
println("Detail: ${problem.detail}")
}
}You can create custom implementations for other HTTP clients:
class MyCustomHolidaysClient(
private val httpClient: MyHttpClient
) : HolidaysClient {
override suspend fun getCountries(languageIsoCode: String?): List<Country> {
// Implement using your preferred HTTP client
val response = httpClient.get("$baseUrl/Countries") {
languageIsoCode?.let { param("languageIsoCode", it) }
}
return parseResponse(response)
}
// Implement other methods...
}See the samples/ folder for runnable Gradle projects:
samples/ktor-sample– CLI app hitting the API via the Ktor clientsamples/spring-sample– coroutine-based sample using the Spring WebClient flavor
┌─────────────────────────────────────────┐
│ Your Application │
│ (Spring Boot, Ktor, Plain Kotlin...) │
└────────────┬────────────────────────────┘
│ depends on
▼
┌─────────────────────────────────────────┐
│ HolidaysClient Interface │
│ (Framework-agnostic) │
│ + Plain Kotlin data classes │
│ + java.time.LocalDate only │
└────────────┬────────────────────────────┘
│ implemented by
┌─────┴──────┐
▼ ▼
┌─────────────┐ ┌──────────────────┐
│ Ktor │ │ Spring WebClient │
│Implementation│ │ Implementation │
└─────────────┘ └──────────────────┘
- Kotlin 1.9+
- JVM 17+ (for the library itself; JVM 11+ if you provide your own Spring dependencies)
- Uses
java.time.LocalDatefrom JDK (no external date/time dependencies) - (Optional) Ktor 3.1+ or Spring WebFlux 6.2+
MIT-License
Generating the artifact
./gradlew clean publishMavenJavaPublicationToCentralPortalRepositoryContributions are welcome! Please feel free to submit a Pull Request.
For detailed API documentation, visit OpenHolidays API Documentation.