
Auto-generates Ktor HTTP client implementations from annotated interfaces via KSP, including factory-extension creation to eliminate boilerplate; supports all HTTP methods, parameter annotations, multipart and form requests.
Ktor Generator is a powerful KSP (Kotlin Symbol Processing) library that automates the creation of Ktor HTTP client implementations for your Kotlin Multiplatform projects. By simply annotating an interface, you can eliminate the boilerplate code required for API service definitions.
It includes:
@ApiService annotation.@GET, @POST, @PUT, @DELETE, @PATCH, @HEAD,
@OPTIONS.@Path, @Query, Body, @Header,
@Part, @Field, and @FieldMap.@FormUrlEncoded and @Multipart.Note: Please replace x.y.z with the latest version.
In your module-level build.gradle.kts file (e.g., shared/build.gradle.kts):
plugins {
// Make sure you have the KSP plugin applied
id("com.google.devtools.ksp")
}
// ...
dependencies {
// Add the annotations library
implementation("io.github.the-best-is-best:ktorgenerator-annotations:x.y.z")
// Add the KSP processor
ksp("io.github.the-best-is-best:ktor-generator-processor:x.y.z")
}Ensure the generated code is included in your source sets. This allows your project to see the code created by the KSP processor.
kotlin {
sourceSets.all {
kotlin.srcDir("build/generated/ksp/$name/kotlin")
}
}*Note: The path might need to be adjusted based on your project structure, but
build/generated/ksp/$name/kotlin covers most standard KMP setups._
@ApiService: Marks an interface to be processed. Ktor Generator will create an implementation
for it.@GET(path: String)@POST(path: String)@PUT(path: String)@DELETE(path: String)@PATCH(path: String)@HEAD(path: String)@OPTIONS(path: String)@Headers(vararg val value: String): Add multiple static headers to a request.@Multipart: Denotes a multipart request.@FormUrlEncoded: Denotes a URL-encoded form request.@TextResponse: Makes the function return the raw response body as a String.@Path(value: String): Replace a placeholder in the request URL path (e.g., users/{id}).@Query(value: String): Add a query parameter to the URL.@Body: Use the annotated parameter as the request body.@Header(value: String): Add a request header.@Field(value: String): A single field in a URL-encoded form.@FieldMap: A Map of key-value pairs for a URL-encoded form.@Part(value: String): A single part in a multipart request.Create an interface and annotate it with @ApiService. Define your API endpoints as functions with
HTTP method and parameter annotations.
// commonMain/kotlin/com/example/api/MyApiService.kt
package com.example.api
import io.github.tbib.ktorgenerator.annotations.annotations.*
// Assume User and Post data classes exist
// data class User(...)
// data class Post(...)
@ApiService
interface MyApiService {
@GET("users/{id}")
suspend fun getUser(@Path("id") userId: String): User
@POST("users")
suspend fun createUser(@Body user: User)
@GET("posts")
suspend fun getPostsByAuthor(@Query("author") authorId: String): List<Post>
}In your application's setup code (e.g., in your DI setup or application entry point), configure the
KtorGeneratorClient with your base URL and a Ktor HttpClient instance.
// commonMain/kotlin/com/example/di/NetworkModule.kt
package com.example.di
import io.github.tbib.ktorgenerator.annotations.engine.KtorGeneratorClient
import io.ktor.client.*
import io.ktor.client.plugins.contentnegotiation.*
import io.ktor.serialization.kotlinx.json.*
import kotlinx.serialization.json.Json
fun initializeNetwork() {
// Configure the Ktor client
val ktorClient = HttpClient {
install(ContentNegotiation) {
json(Json {
prettyPrint = true
isLenient = true
ignoreUnknownKeys = true
})
}
// Add other plugins like Logging, Auth, etc.
}
// Assign the base URL and the client to the generator
KtorGeneratorClient.baseUrl = "https://api.example.com/v1/"
KtorGeneratorClient.ktorClient = ktorClient
}After building the project, KSP will generate the implementation and a create<YourInterfaceName>
extension function. You can then get your API service instance directly from KtorGeneratorClient.
// After initialization in your ViewModel or Presenter
val myApi: MyApiService = KtorGeneratorClient.createMyApiService()
// Now you can make API calls
suspend fun fetchSomeUser() {
val user = myApi.getUser("123")
println("Fetched user: $user")
}Ktor Generator is a powerful KSP (Kotlin Symbol Processing) library that automates the creation of Ktor HTTP client implementations for your Kotlin Multiplatform projects. By simply annotating an interface, you can eliminate the boilerplate code required for API service definitions.
It includes:
@ApiService annotation.@GET, @POST, @PUT, @DELETE, @PATCH, @HEAD,
@OPTIONS.@Path, @Query, Body, @Header,
@Part, @Field, and @FieldMap.@FormUrlEncoded and @Multipart.Note: Please replace x.y.z with the latest version.
In your module-level build.gradle.kts file (e.g., shared/build.gradle.kts):
plugins {
// Make sure you have the KSP plugin applied
id("com.google.devtools.ksp")
}
// ...
dependencies {
// Add the annotations library
implementation("io.github.the-best-is-best:ktorgenerator-annotations:x.y.z")
// Add the KSP processor
ksp("io.github.the-best-is-best:ktor-generator-processor:x.y.z")
}Ensure the generated code is included in your source sets. This allows your project to see the code created by the KSP processor.
kotlin {
sourceSets.all {
kotlin.srcDir("build/generated/ksp/$name/kotlin")
}
}*Note: The path might need to be adjusted based on your project structure, but
build/generated/ksp/$name/kotlin covers most standard KMP setups._
@ApiService: Marks an interface to be processed. Ktor Generator will create an implementation
for it.@GET(path: String)@POST(path: String)@PUT(path: String)@DELETE(path: String)@PATCH(path: String)@HEAD(path: String)@OPTIONS(path: String)@Headers(vararg val value: String): Add multiple static headers to a request.@Multipart: Denotes a multipart request.@FormUrlEncoded: Denotes a URL-encoded form request.@TextResponse: Makes the function return the raw response body as a String.@Path(value: String): Replace a placeholder in the request URL path (e.g., users/{id}).@Query(value: String): Add a query parameter to the URL.@Body: Use the annotated parameter as the request body.@Header(value: String): Add a request header.@Field(value: String): A single field in a URL-encoded form.@FieldMap: A Map of key-value pairs for a URL-encoded form.@Part(value: String): A single part in a multipart request.Create an interface and annotate it with @ApiService. Define your API endpoints as functions with
HTTP method and parameter annotations.
// commonMain/kotlin/com/example/api/MyApiService.kt
package com.example.api
import io.github.tbib.ktorgenerator.annotations.annotations.*
// Assume User and Post data classes exist
// data class User(...)
// data class Post(...)
@ApiService
interface MyApiService {
@GET("users/{id}")
suspend fun getUser(@Path("id") userId: String): User
@POST("users")
suspend fun createUser(@Body user: User)
@GET("posts")
suspend fun getPostsByAuthor(@Query("author") authorId: String): List<Post>
}In your application's setup code (e.g., in your DI setup or application entry point), configure the
KtorGeneratorClient with your base URL and a Ktor HttpClient instance.
// commonMain/kotlin/com/example/di/NetworkModule.kt
package com.example.di
import io.github.tbib.ktorgenerator.annotations.engine.KtorGeneratorClient
import io.ktor.client.*
import io.ktor.client.plugins.contentnegotiation.*
import io.ktor.serialization.kotlinx.json.*
import kotlinx.serialization.json.Json
fun initializeNetwork() {
// Configure the Ktor client
val ktorClient = HttpClient {
install(ContentNegotiation) {
json(Json {
prettyPrint = true
isLenient = true
ignoreUnknownKeys = true
})
}
// Add other plugins like Logging, Auth, etc.
}
// Assign the base URL and the client to the generator
KtorGeneratorClient.baseUrl = "https://api.example.com/v1/"
KtorGeneratorClient.ktorClient = ktorClient
}After building the project, KSP will generate the implementation and a create<YourInterfaceName>
extension function. You can then get your API service instance directly from KtorGeneratorClient.
// After initialization in your ViewModel or Presenter
val myApi: MyApiService = KtorGeneratorClient.createMyApiService()
// Now you can make API calls
suspend fun fetchSomeUser() {
val user = myApi.getUser("123")
println("Fetched user: $user")
}