eu.metaengine:metaengine-graphql-kotlin-ktor-maven-plugin
GraphQL SDL → Kotlin Ktor HTTP client services and models, delivered as a Maven plugin. Typed queries, mutations & subscriptions over a Ktor HttpClient with kotlinx.serialization models (subscriptions surface as Flow<T> over client.webSocket using the graphql-transport-ws subprotocol), plus bearer/basic auth, retries, timeouts, and error handling — generated straight into your build at generate-sources.
Pick your registry
The same generator, published to every ecosystem we support. Install however your project expects.
Drive it from Maven or programmatically
Maven Central ships a build-time plugin that runs inside your build. NuGet ships the same generator as a C# fluent API — same options, same output.
Add the plugin to your pom.xml. Its generate goal binds to the generate-sources phase, so the Ktor client and models are produced — and added to your compile roots — on every mvn compile or package. Point <inputSpec> at a GraphQL SDL file or URL and set the target Kotlin <packageName>.
<build>
<plugins>
<plugin>
<groupId>eu.metaengine</groupId>
<artifactId>metaengine-graphql-kotlin-ktor-maven-plugin</artifactId>
<version>1.0.0</version>
<executions>
<execution>
<id>generate-graphql-client</id>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<inputSpec>${project.basedir}/src/main/resources/schema.graphql</inputSpec>
<packageName>com.example.api</packageName>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>The generate goal binds to the generate-sources phase, so a normal mvn compile (or package) produces the client and registers it as a compile source root — no extra wiring. <inputSpec> accepts a local path or an http(s) URL; GraphQL SDL is also accepted as inline content. Queries, mutations and subscriptions are generated (subscriptions resolve to a Flow<T> over Ktor client.webSocket using the graphql-transport-ws subprotocol).
<configuration>
<inputSpec>${project.basedir}/schema.graphql</inputSpec>
<packageName>com.example.api</packageName>
<bearerAuth>API_TOKEN</bearerAuth>
<timeout>30</timeout>
<retry>3</retry>
<errorHandling>true</errorHandling>
</configuration><configuration>
<inputSpec>https://api.example.com/schema.graphql</inputSpec>
<packageName>com.example.api</packageName>
<fragments>true</fragments>
<subscriptionUrl>/graphql-subscriptions</subscriptionUrl>
<documentation>true</documentation>
</configuration><configuration>
<inputSpec>${project.basedir}/schema.graphql</inputSpec>
<packageName>com.example.api</packageName>
<basicAuth>API_USER,API_PASS</basicAuth>
<customHeaders>
<customHeader>X-Tenant-ID:TENANT_ID</customHeader>
</customHeaders>
</configuration>Every knob, documented
Every option is available on the C# fluent API as a method; the Maven plugin exposes most as <configuration> elements. Cross-cutting auth, headers, retries and timeouts apply across frameworks.
Auth · Headers · Resilience
13WithErrorHandling()Smart error handling on the Ktor client based on HTTP status (404 / 403 → null · 400 / 422 → error body · 401 / 5xx → throw). GraphQL operations travel over HTTP POST.WithErrorHandling(errors => errors...)Per-status routing: ReturnNullFor(404, 403) · ReturnErrorFor(400, 422) · ThrowFor(401, 500)WithBearerAuth()Bearer token from env var (default API_TOKEN) — adds Authorization headerWithBearerAuth(string)Bearer token from a specific env var nameWithBearerAuth(string, string)Bearer token with custom header name (e.g. X-Api-Key)WithBasicAuth()HTTP Basic auth from default env vars (API_USERNAME / API_PASSWORD)WithBasicAuth(string, string)HTTP Basic auth from username + password env varsWithCustomHeader(string, string)Static header from env var. Repeatable (e.g. X-Tenant-ID ← TENANT_ID)WithTimeout(double)Request timeout in seconds — sets Ktor connect, request and socket timeouts togetherWithTimeout(double?, double?, double?)Granular timeout: connect · read · write (Ktor HttpTimeout has no connection-pool timeout)WithRetries()Retries with exponential backoff (default status 429, 503)WithRetries(int)Retries with custom max attemptsWithRetries(int, double, double, int[])Retries with full custom settings including status codes
Kotlin Options
3WithDocumentation()Generate KDoc comments on methods and parameters from SDL descriptionsWithMethodNames(Func)Custom method naming ruleWithOptionsObjectThreshold(int)Parameter count for options object (default: 4)
GraphQL Options
8WithDocumentation()Generate KDoc comments from SDL type & field descriptionsWithFragments()Emit reusable named fragments for object-type selections (...TypeFields spreads)WithOneOfInputs()Generate idiomatic @oneOf input types (tagged-union inputs where exactly one field is set)WithCustomScalar(string, Type)Map a GraphQL custom scalar to a Kotlin type (e.g. DateTime → kotlinx.datetime.Instant). Unmapped scalars default to StringWithSubscriptionUrl(string)Path appended to baseUrl for the GraphQL WebSocket subscription endpoint (default: /graphql). The client upgrades http→ws / https→wss; subscriptions surface as Flow<T> over the graphql-transport-ws subprotocolWithTypeFilter(Func)Filter extracted GraphQL types before registration — only types returning true are generatedWithMethodNames(Func)Custom method naming ruleWithOptionsObjectThreshold(int)Parameter count for options object (default: 4)
Naming Transformations
3Types(Func)Transform type namesPaths(Func)Transform output pathsFileNames(Func)Transform file names
File Management
5CleanDestination()Clean output directory before generationAlwaysOverwrite()Always overwrite existing filesOnlyWhenModelChanged()Update only when model changesOnlyWhenNew()Write only new files, preserve existingCleanDirectories(...)Clean specific subdirectories
Diagnostics
1EnableVerboseLogging()Enable detailed logging