Cette page parcourt les motifs OpenAPI 3.1 couramment rencontrés dans une API JAX-RS réelle, et montre comment les exprimer avec les annotations MicroProfile OpenAPI 4.1 supportées par Grimm.
Pagination par query parameters
Les paramètres page et size sont décrits par @Parameter. Les valeurs par défaut sont visibles dans le schéma via Schema.defaultValue.
@GET
@Produces(MediaType.APPLICATION_JSON)
@Operation(summary = "Liste paginée d'animaux")
public PetPage list(
@Parameter(description = "Numéro de page (zero-based)")
@QueryParam("page") @DefaultValue("0") int page,
@Parameter(description = "Taille de page, max 100")
@QueryParam("size") @DefaultValue("20") int size) {
/* ... */
}
@Schema(name = "PetPage")
public record PetPage(
@Schema(description = "Éléments de la page") List<Pet> items,
@Schema(description = "Nombre total d'éléments") long total) { }
Polymorphisme : oneOf + discriminator
Un type abstrait sérialisé selon plusieurs formes concrètes se décrit avec @Schema(oneOf = …, discriminatorProperty = …). Grimm émet oneOf, discriminator.propertyName et discriminator.mapping.
@Schema(
oneOf = { Dog.class, Cat.class },
discriminatorProperty = "kind",
discriminatorMapping = {
@DiscriminatorMapping(value = "dog", schema = Dog.class),
@DiscriminatorMapping(value = "cat", schema = Cat.class)
}
)
public sealed interface Pet permits Dog, Cat { String kind(); }
public record Dog(String kind, String breed) implements Pet { }
public record Cat(String kind, boolean indoor) implements Pet { }
Sécurité — @SecurityScheme
Une fois déclaré au niveau Application, le schéma est référencé par @SecurityRequirement sur les opérations.
@SecurityScheme(
securitySchemeName = "bearerAuth",
type = SecuritySchemeType.HTTP,
scheme = "bearer",
bearerFormat = "JWT"
)
@OpenAPIDefinition(info = @Info(title = "Pet Store", version = "1.0.0"))
public class PetStoreApp extends Application { }
@GET
@Path("/admin/pets")
@SecurityRequirement(name = "bearerAuth")
@Operation(summary = "Vue administrateur — JWT requis")
public List<Pet> adminList() { /* ... */ }
|
La conformité JWT côté runtime relève de Cervantes (MP JWT 2.1). Grimm se limite à documenter le schéma de sécurité. Voir Cervantes. |
Serveurs multiples
Plusieurs serveurs cibles : @Server répétable au niveau Application ou opération.
@Server(url = "https://api.example.com", description = "Production")
@Server(url = "https://staging.api.example.com", description = "Staging")
@OpenAPIDefinition(info = @Info(title = "Pet Store", version = "1.0.0"))
public class PetStoreApp extends Application { }
Surcharge possible sans recompilation via mp.openapi.servers=https://api.example.com,https://staging.api.example.com. Voir Référence.
Callbacks
Un callback décrit un endpoint que le serveur appellera ultérieurement (webhook). Grimm émet un noeud callbacks sur l’opération concernée.
@POST
@Path("/subscriptions")
@Operation(summary = "S'abonner aux événements d'animaux")
@Callback(
name = "petUpdated",
callbackUrlExpression = "{$request.body#/callbackUrl}",
operations = @CallbackOperation(
method = "POST",
summary = "Notification de mise à jour d'animal",
requestBody = @RequestBody(content = @Content(schema = @Schema(implementation = Pet.class)))
)
)
public Response subscribe(SubscriptionRequest req) { /* ... */ }
Exemples (@ExampleObject)
Des exemples nommés enrichissent la documentation rendue par Swagger UI ou Redoc.
@POST
@Operation(summary = "Crée un animal")
@RequestBody(
content = @Content(
schema = @Schema(implementation = Pet.class),
examples = {
@ExampleObject(name = "Rex", value = "{ \"name\": \"Rex\", \"kind\": \"dog\" }"),
@ExampleObject(name = "Whiskers", value = "{ \"name\": \"Whiskers\", \"kind\": \"cat\" }")
}
)
)
public Response create(Pet pet) { /* ... */ }
Liens HATEOAS
Le noeud links exprime la navigation hypermédia : operationId ou operationRef, paramètres exprimés via runtime expressions.
@APIResponse(
responseCode = "201",
description = "Animal créé",
links = @Link(
name = "GetPetById",
operationId = "findPet",
parameters = @LinkParameter(name = "id", expression = "$response.body#/id")
)
)
public Response create(Pet pet) { /* ... */ }
Version (info.version)
La version du contrat est portée par @Info(version = …). Pour une lecture dynamique à partir du build, surcharger via MP Config :
mp.openapi.servers=https://api.example.com
# La version du contrat n'a pas de clé MP Config dédiée :
# soit elle est codée en dur dans @Info, soit elle est calculée
# par un OASModelReader qui lit `application.version` depuis le manifest.
Tag
@Tag regroupe les opérations sous un libellé partagé. Utilisable au niveau classe ou méthode, répétable.
@Path("/pets")
@Tag(name = "pets", description = "Gestion des animaux")
public class PetResource {
@GET @Operation(summary = "Liste")
public List<Pet> list() { /* ... */ }
}
Pour aller plus loin
-
Référence — table exhaustive des annotations et clés.
-
Concepts — fusion des sources, filtres.
-
Fonctionnement interne — pipeline détaillé.