Versioning
The annotated routing module provides built-in support for API versioning through HTTP headers. Multiple versions of the same endpoint can coexist in the same class.
Basic Usage
Use the @Version annotation to define versioned endpoints:
java
@Endpoints("/api")
class UserEndpoints {
@Version("1")
@Get("/users/{name}")
void getUserV1(Context ctx, @Param String name) {
ctx.result("V1: " + name);
}
@Version("2")
@Get("/users/{name}")
void getUserV2(Context ctx, @Param String name) {
ctx.json(Map.of("version", "2", "name", name));
}
}Client Usage
Clients specify the desired version via an HTTP header. By default, the header is X-API-Version:
GET /api/users/john
X-API-Version: 2If the client requests a version that doesn't exist for the endpoint, the server responds with 400 Bad Request.
Custom Version Header
Configure a custom header name during setup:
kotlin
config.routes(Annotated) {
apiVersionHeader = "X-Custom-Version"
registerEndpoints(UserEndpoints())
}java
AnnotatedRouting.install(config, routing -> {
routing.apiVersionHeader = "X-Custom-Version";
routing.registerEndpoints(new UserEndpoints());
});How It Works
- Routes with
@Versionare grouped by their HTTP method and path - A single handler is registered for each group
- When a request arrives, the plugin reads the version header
- The corresponding versioned handler is invoked
- If the requested version is not available, a
400 Bad Requestresponse is returned
Combining with @OpenApi
Version annotations work with the Javalin OpenAPI plugin:
java
@OpenApi(
path = "/api/users/{name}",
methods = { GET },
versions = { "default", "2" },
responses = {
@OpenApiResponse(
status = "200",
content = @OpenApiContent(from = UserDto.class)
)
}
)
@Version("2")
@Get("/users/{name}")
void getUserV2(Context ctx, @Param String name) { }