{"id":36606257,"url":"https://github.com/turbomates/ktor-open-api","last_synced_at":"2026-01-12T08:45:39.515Z","repository":{"id":37927549,"uuid":"496384184","full_name":"turbomates/ktor-open-api","owner":"turbomates","description":null,"archived":false,"fork":false,"pushed_at":"2025-11-04T22:51:36.000Z","size":143,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-11-05T00:18:21.942Z","etag":null,"topics":["kotlin","openapi","swagger"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/turbomates.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2022-05-25T20:43:18.000Z","updated_at":"2025-11-04T22:51:21.000Z","dependencies_parsed_at":"2022-07-07T23:13:08.456Z","dependency_job_id":null,"html_url":"https://github.com/turbomates/ktor-open-api","commit_stats":null,"previous_names":["turbomates/ktor-openapi"],"tags_count":18,"template":false,"template_full_name":null,"purl":"pkg:github/turbomates/ktor-open-api","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/turbomates%2Fktor-open-api","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/turbomates%2Fktor-open-api/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/turbomates%2Fktor-open-api/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/turbomates%2Fktor-open-api/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/turbomates","download_url":"https://codeload.github.com/turbomates/ktor-open-api/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/turbomates%2Fktor-open-api/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28337599,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-12T06:09:07.588Z","status":"ssl_error","status_checked_at":"2026-01-12T06:05:18.301Z","response_time":98,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["kotlin","openapi","swagger"],"created_at":"2026-01-12T08:45:39.452Z","updated_at":"2026-01-12T08:45:39.506Z","avatar_url":"https://github.com/turbomates.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"![](https://turbomates.com/wp-content/uploads/2019/11/logo-e1573642672476.png)\n\n[![Project Status: WIP – Initial development is in progress, but there has not yet been a stable, usable release suitable for the public.](https://www.repostatus.org/badges/latest/wip.svg)](https://www.repostatus.org/#wip)\n\n# Ktor OpenAPI\n\nAutomatically generate OpenAPI 3.0 documentation for your Ktor application based on routing definitions and Kotlin type information. This library uses Kotlin reflection and reified generics to build accurate OpenAPI specifications without manual schema definitions.\n\n## Features\n\n- **Automatic Schema Generation**: Generates OpenAPI schemas from Kotlin types using reflection\n- **Type-Safe**: Uses reified generics to capture request/response types at compile time\n- **Zero Boilerplate**: No need to manually write OpenAPI annotations or schema definitions\n- **Comprehensive Type Support**:\n  - Primitive types (String, Number, Boolean, UUID, Duration, Locale)\n  - Collections (List, Set, Array)\n  - Maps\n  - Enums\n  - Value classes (inline classes)\n  - Generic type parameters\n  - Nested objects\n- **Path, Query, and Body Parameters**: Automatically extracts parameter definitions from route signatures\n- **Swagger UI Integration**: Built-in Swagger UI for interactive API documentation\n- **Custom Type Mapping**: Configure custom OpenAPI types for specific Kotlin types\n\n## Installation\n\nAdd the dependency to your `build.gradle.kts`:\n\n```kotlin\ndependencies {\n    implementation(\"com.turbomates:ktor-openapi:VERSION\")\n}\n```\n\n## Quick Start\n\n### 1. Install the Plugin\n\n```kotlin\nimport com.turbomates.openapi.ktor.OpenAPI\nimport com.turbomates.openapi.OpenAPI as SwaggerOpenAPI\n\nfun Application.module() {\n    install(OpenAPI) {\n        documentationBuilder = SwaggerOpenAPI(\"api.example.com\")\n        path = \"/openapi.json\"  // OpenAPI spec endpoint (default)\n    }\n\n    routing {\n        // Your routes here\n    }\n}\n```\n\n### 2. Define Type-Safe Routes\n\n```kotlin\nimport com.turbomates.openapi.ktor.*\n\n// Simple GET endpoint with typed response\nget\u003cUserResponse\u003e(\"/users/{id}\") { params -\u003e\n    val userId = call.parameters[\"id\"]\n    // ... fetch user\n    UserResponse(id = userId, name = \"John Doe\")\n}\n\n// POST with request body\npost\u003cCreatedResponse, CreateUserRequest\u003e(\"/users\") { request -\u003e\n    // ... create user\n    CreatedResponse(id = UUID.randomUUID())\n}\n\n// GET with query parameters\nget\u003cList\u003cUserResponse\u003e, UserQueryParams\u003e(\"/users\") { queryParams -\u003e\n    // ... fetch users with filters\n    listOf(UserResponse(...))\n}\n\n// Complex example with path and body parameters\npost\u003cResponse.Either\u003cResponse.Data\u003cUUID\u003e, Response.Errors\u003e, RegisterUser\u003e(\"/register\") { command -\u003e\n    command.locale = call.resolveLocale()\n    controller\u003cUserController\u003e(this).register(command)\n}\n```\n\n### 3. Access Documentation\n\n- **OpenAPI Spec**: `http://localhost:8080/openapi.json`\n- **Swagger UI**: `http://localhost:8080/swagger-ui/index.html`\n\n## Usage\n\n### HTTP Method Extensions\n\nThe library provides type-safe extension functions for all HTTP methods:\n\n#### GET\n\n```kotlin\n// Simple response\nget\u003cUserResponse\u003e(\"/users/{id}\") { params -\u003e\n    UserResponse(...)\n}\n\n// With query parameters\nget\u003cList\u003cUserResponse\u003e, UserQueryParams\u003e(\"/users\") { query -\u003e\n    // query.limit, query.offset, etc.\n    listOf(UserResponse(...))\n}\n```\n\n#### POST\n\n```kotlin\n// With request body\npost\u003cCreatedResponse, CreateUserRequest\u003e(\"/users\") { body -\u003e\n    CreatedResponse(id = service.create(body))\n}\n\n// With query parameters and body\npost\u003cUpdatedResponse, QueryParams, UpdateRequest\u003e(\"/users\") { query, body -\u003e\n    UpdatedResponse(...)\n}\n```\n\n#### PUT\n\n```kotlin\nput\u003cUserResponse, UpdateUserRequest\u003e(\"/users/{id}\") { body -\u003e\n    UserResponse(...)\n}\n```\n\n#### PATCH\n\n```kotlin\npatch\u003cUserResponse, PatchUserRequest\u003e(\"/users/{id}\") { body -\u003e\n    UserResponse(...)\n}\n```\n\n#### DELETE\n\n```kotlin\ndelete\u003cDeleteResponse\u003e(\"/users/{id}\") { params -\u003e\n    DeleteResponse(success = true)\n}\n```\n\n### Configuration\n\n#### Basic Configuration\n\n```kotlin\ninstall(OpenAPI) {\n    documentationBuilder = SwaggerOpenAPI(\"api.example.com\")\n    path = \"/openapi.json\"\n}\n```\n\n#### Advanced Configuration\n\n```kotlin\ninstall(OpenAPI) {\n    documentationBuilder = SwaggerOpenAPI(\"api.example.com\")\n    path = \"/openapi.json\"\n\n    // Custom response code mapping\n    responseCodeMap = {\n        mapOf(\n            HttpStatusCode.OK.value to this,\n            HttpStatusCode.Created.value to this\n        )\n    }\n\n    // Custom type descriptions for specific types\n    customTypeDescription = mapOf(\n        typeOf\u003cMyCustomType\u003e() to Type(\n            type = DataType.STRING,\n            format = \"custom-format\",\n            description = \"Custom type description\"\n        )\n    )\n\n    // Additional configuration\n    configure = { openAPI -\u003e\n        openAPI.info.title = \"My API\"\n        openAPI.info.version = \"1.0.0\"\n        openAPI.info.description = \"API documentation\"\n    }\n}\n```\n\n### Type System\n\nThe library automatically converts Kotlin types to OpenAPI schemas:\n\n| Kotlin Type | OpenAPI Type | Format |\n|-------------|--------------|--------|\n| String | string | - |\n| Int, Long | integer | int32, int64 |\n| Float, Double | number | float, double |\n| Boolean | boolean | - |\n| UUID | string | uuid |\n| Duration | string | duration |\n| Locale | string | - |\n| LocalDate | string | date |\n| LocalDateTime | string | date-time |\n| List, Set, Array | array | - |\n| Map | object | - |\n| Enum | string | enum values |\n| Value Class | (unwrapped type) | - |\n\n#### Complex Types\n\n```kotlin\ndata class UserResponse(\n    val id: UUID,\n    val name: String,\n    val email: String,\n    val roles: List\u003cRole\u003e,\n    val metadata: Map\u003cString, Any\u003e\n)\n\nenum class Role {\n    ADMIN, USER, GUEST\n}\n```\n\nThe above will automatically generate:\n\n```json\n{\n  \"UserResponse\": {\n    \"type\": \"object\",\n    \"properties\": {\n      \"id\": { \"type\": \"string\", \"format\": \"uuid\" },\n      \"name\": { \"type\": \"string\" },\n      \"email\": { \"type\": \"string\" },\n      \"roles\": {\n        \"type\": \"array\",\n        \"items\": { \"type\": \"string\", \"enum\": [\"ADMIN\", \"USER\", \"GUEST\"] }\n      },\n      \"metadata\": { \"type\": \"object\" }\n    }\n  }\n}\n```\n\n## Build \u0026 Development\n\n### Building\n\n```bash\n./gradlew build\n# or\nmake gradlew-build  # alias: make gb\n```\n\n### Testing\n\n```bash\n./gradlew test\n# or\nmake test  # alias: make t\n```\n\nRun a specific test:\n\n```bash\n./gradlew test --tests \"com.turbomates.openapi.ktor.OpenAPITest\"\n```\n\n### Linting (Detekt)\n\n```bash\n# Run all detekt checks\nmake detekt  # alias: make d\n\n# Run detekt on main sources only\n./gradlew detektMain\n# or: make detekt-main (alias: make dm)\n\n# Run detekt on test sources only\n./gradlew detektTest\n# or: make detekt-test (alias: make dt)\n```\n\nUpdate detekt baselines:\n\n```bash\nmake detekt-baseline-main  # alias: make dbm\nmake detekt-baseline-test  # alias: make dbt\n```\n\n### View Available Tasks\n\n```bash\n./gradlew tasks\n# or\nmake gradlew-tasks  # alias: make gt\n```\n\n## Architecture\n\n### Core Components\n\n1. **OpenAPI Builder** (`com.turbomates.openapi.OpenAPI`): Core class that builds the OpenAPI specification. Manages paths, operations, schemas, and custom type mappings.\n\n2. **Ktor Plugin** (`com.turbomates.openapi.ktor.OpenAPI`): Ktor plugin that integrates with the routing system. Installs the `/openapi.json` endpoint and intercepts route definitions to extract type information.\n\n3. **Type System** (`OpenApiKType`): Reflection-based type introspection that converts Kotlin types to OpenAPI type definitions.\n\n4. **HTTP Method Extensions**: Extension functions for Ktor routing that capture type information via reified generics.\n\n### Key Design Patterns\n\n- **Reified Type Capture**: Uses inline reified functions to capture types at compile time\n- **Type Merging**: Routes defined multiple times have their specifications merged\n- **Custom Type Mapping**: Plugin configuration allows mapping specific types to custom OpenAPI definitions\n\n## Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request.\n\n## License\n\n[Add your license information here]\n\n## Support\n\nFor issues, questions, or contributions, please visit the [GitHub repository](https://github.com/turbomates/ktor-open-api).","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fturbomates%2Fktor-open-api","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fturbomates%2Fktor-open-api","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fturbomates%2Fktor-open-api/lists"}