Getting started
Dependency
conta-http is published to the conta-open group Maven registry.
repositories {
mavenCentral()
maven {
name 'contaOpen'
url 'https://gitlab.com/api/v4/groups/12992043/-/packages/maven'
}
}
dependencies {
implementation 'no.conta.http:conta-http-kit:0.+'
}
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:1.+'
}
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 carry no serialization annotations, so they 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
An application on micronaut-serde instead of databind must register the envelopes it returns with @SerdeImport, e.g. @SerdeImport(SingleEnvelope.class) / @SerdeImport(SliceEnvelope.class), since the types are deliberately annotation-free.
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.