Getting started
Dependency
conta-http is published to the conta-open group Maven registry.
Pick the line that matches your Micronaut version:
| conta-http | Micronaut | Java |
|---|---|---|
0.8.x |
5.x |
25 |
0.7.x |
4.x |
17 |
A Micronaut 4 application pins 0.7.+, not 0.+: the 0.8.x jars are Java 25 class files and pull conta-problem-json 2.x.
repositories {
mavenCentral()
maven {
name 'contaOpen'
url 'https://gitlab.com/api/v4/groups/12992043/-/packages/maven'
}
}
dependencies {
implementation 'no.conta.http:conta-http-kit:0.8.+'
}
Micronaut wiring
conta-http-kit carries the Micronaut annotation processor metadata, so Paging binds with @RequestBean and QueryParamGuard can introspect your query beans without further configuration.
The library throws no.conta.problem.ThrowableProblem for rejected requests but does not ship an exception handler.
To render those as application/problem+json, the consuming application must depend on conta-problem-json-mn, which provides the handler.
dependencies {
implementation 'no.conta.problem:conta-problem-json-mn:2.+'
}
conta-problem-json-mn extracts an OpenTelemetry trace into the problem response, so the application must also have io.opentelemetry:opentelemetry-api on its runtime classpath (Micronaut tracing already provides it).
|
Serialization
The envelope types serialize by reflection under micronaut-jackson-databind:
dependencies {
implementation 'io.micronaut:micronaut-jackson-databind'
}
Configure the ObjectMapper to omit nulls so optional fields are absent rather than null:
jackson:
serialization-inclusion: NON_NULL
The _related and _links fields carry @JsonProperty, the only annotations on the envelopes, because Jackson 3 does not read get_related() as a getter.
jackson-annotations comes with conta-http-kit; both Jackson 3 and serde honor it.
Jackson 3 writes keys in alphabetical order, so _links and _related come first and kind lands in the middle.
A JSON parser does not care, and conta-http sets nothing.
Turning the sorting off brings back Jackson’s discovery order, the 0.7.x order except that _related and _links come last:
jackson:
mapper-features:
SORT_PROPERTIES_ALPHABETICALLY: false
An application on micronaut-serde instead of databind lists no.conta.http in micronaut.serde.included-introspection-packages (next to the default io.micronaut), so serde uses the bean introspections conta-http ships.
Do not @SerdeImport the envelopes: that registers a second introspection for the same type, and Micronaut keeps whichever it loads last.
A complete controller
@Controller("/widgets")
public class WidgetController {
private final QueryParamGuard queryParamGuard = QueryParamGuard.fromBeans(Paging.class, WidgetQuery.class);
private final OrderFieldsGuard orderFieldsGuard = OrderFieldsGuard.fromFields(WidgetOrderField.allowedNames());
private final WidgetService service;
public WidgetController(WidgetService service) {
this.service = service;
}
@Get("{?queryParams*}")
public SliceEnvelope<Widget> list(
@RequestBean Paging paging,
@RequestBean WidgetQuery query,
@Nullable @QueryValue Map<String, String> queryParams
) {
queryParamGuard.rejectUnknown(queryParams);
orderFieldsGuard.requireAllowed(paging.getOrderByField());
var page = service.find(query, paging.toPageableWithDefaults("createdAt", Direction.DESC));
return Envelopes.slice(page);
}
}
Read on:
-
Paging — request-side pagination.
-
Response envelope — response-side shaping.
-
Query-param smuggle-rejection — query-param and order-field validation.