44 votes

Comment puis-je définir une description et un exemple dans Swagger avec les annotations Swagger ?

Je suis en train de créer une Api REST en utilisant Spring boot, et en générant automatiquement la documentation swagger dans les contrôleurs en utilisant swagger codegen. Cependant, je ne suis pas en mesure de définir une description et un exemple pour un paramètre de type String dans une requête POST. Voici mon code :

import io.swagger.annotations.*;

@Api(value = "transaction", tags = {"transaction"})
@FunctionalInterface
public interface ITransactionsApi {
    @ApiOperation(value = "Places a new transaction on the system.", notes = "Creates a new transaction in the system. See the schema of the Transaction parameter for more information ", tags={ "transaction", })
    @ApiResponses(value = {
        @ApiResponse(code = 200, message = "Another transaction with the same messageId already exists in the system. No transaction was created."),
        @ApiResponse(code = 201, message = "The transaction has been correctly created in the system"),
        @ApiResponse(code = 400, message = "The transaction schema is invalid and therefore the transaction has not been created.", response = String.class),
        @ApiResponse(code = 415, message = "The content type is unsupported"),
        @ApiResponse(code = 500, message = "An unexpected error has occurred. The error has been logged and is being investigated.") })

    @RequestMapping(value = "/transaction",
        produces = { "text/plain" },
        consumes = { "application/json" },
        method = RequestMethod.POST)
    ResponseEntity<Void> createTransaction(
        @ApiParam(
            value = "A JSON value representing a transaction. An example of the expected schema can be found down here. The fields marked with an * means that they are required." ,
            example = "{foo: whatever, bar: whatever2}")
        @Valid @RequestBody String kambiTransaction) throws InvalidTransactionException;
}

La propriété d'exemple de l'@ApiParam a été insérée manuellement par moi, parce que le codegen ignorait cette partie du yaml (C'est une autre question : pourquoi l'éditeur ignore-t-il la partie d'exemple ?). Voici une partie du yaml :

paths:
  /transaction:
    post:
      tags:
        - transaction
      summary: Place a new transaction on the system.
      description: >
        Creates a new transaction in the system. See the schema of the Transaction parameter
        for more information
      operationId: createTransaction
      parameters:
        - $ref: '#/parameters/transaction'
      consumes:
        - application/json
      produces:
        - text/plain
      responses:
        '200':
          description: Another transaction with the same messageId already exists in the system. No transaction was created.
        '201':
          description: The transaction has been correctly created in the system
        '400':
          description: The transaction schema is invalid and therefore the transaction has not been created.
          schema:
            type: string
            description: error message explaining why the request is a bad request.
        '415':
          description: The content type is unsupported
        '500':
          $ref: '#/responses/Standard500ErrorResponse'

parameters:
  transaction:
    name: kambiTransaction
    in: body
    required: true
    description: A JSON value representing a kambi transaction. An example of the expected schema can be found down here. The fields marked with an * means that they are required.
    schema:
      type: string
      example:
        {
          foo*: whatever,
          bar: whatever2
        }

Et enfin, c'est ce que montre Swagger :

enter image description here

Enfin, les dépendances utilisées dans build.gradle sont les suivantes :

compile group: 'io.springfox', name: 'springfox-swagger2', version: '2.7.0'
compile group: 'io.springfox', name: 'springfox-swagger-ui', version: '2.7.0'

Donc, la question est : Quelqu'un sait-il comment je peux définir la description et un exemple d'un paramètre de corps en utilisant les annotations swagger ?

EDIT

J'ai réussi à modifier la description en utilisant @ApiImplicitParam au lieu de @ApiParam, mais l'exemple est toujours absent :

@ApiImplicitParams({
    @ApiImplicitParam(
        name = "kambiTransaction",
        value = "A JSON value representing a transaction. An example of the expected schema can be found down here. The fields marked with * means that they are required. See the schema of KambiTransaction for more information.",
        required = true,
        dataType = "String",
        paramType = "body",
        examples = @Example(value = {@ExampleProperty(mediaType = "application/json", value = "{foo: whatever, bar: whatever2}")}))})

0 votes

Dans votre exemple, vous dites kambiTransaction est de type String mais votre méthode consomme application/json . En d'autres termes, vous voulez envoyer une chaîne de texte brut (qui contient du JSON - comme indiqué dans l'exemple de valeur) enveloppée dans du JSON ? Pourquoi ne pas créer une classe de domaine pour les éléments suivants kambiTransaction . Swagger imprimera automatiquement la structure de la classe comme exemple JSON.

0 votes

Je suis d'accord avec @dpr. La bonne méthode consiste à créer une classe de modèle et à utiliser les annotations. ApiModel sur la classe et ApiModelProperty sur les champs. ApiModelProperty accepte les paramètres valeur et exemple.

30voto

Artem Trofimoff Points 136

J'ai un problème similaire avec la génération d'exemples pour les objets du corps - annotation @Example et @ExampleProperty ne fonctionne tout simplement pas sans raison dans swagger 1.5.x. (J'utilise 1.5.16).

Ma solution actuelle est la suivante :
utiliser @ApiParam(example="...") pour objets non corporels par exemple :

public void post(@PathParam("userId") @ApiParam(value = "userId", example = "4100003") Integer userId) {}

pour corps créer une nouvelle classe d'objets et annoter les champs avec @ApiModelProperty(value = " ", example = " ") par exemple :

@ApiModel(subTypes = {BalanceUpdate.class, UserMessage.class})
class PushRequest {
    @ApiModelProperty(value = "status", example = "push")
    private final String status;;
}

9voto

dpr Points 4084

En fait, la documentation java pour le example de l @ApiParam L'annotation indique que cela doit être utilisé exclusivement pour les paramètres non corporels. Lorsque l'annotation examples peut être utilisée pour les paramètres du corps.

J'ai testé cette annotation

@ApiParam(
  value = "A JSON value representing a transaction. An example of the expected schema can be found down here. The fields marked with an * means that they are required.",
  examples = @Example(value = 
    @ExampleProperty(
      mediaType = MediaType.APPLICATION_JSON,
      value = "{foo: whatever, bar: whatever2}"
    )
  )
)

ce qui a permis de générer le swagger suivant pour la méthode correspondante :

/transaction:
  post:
  ...
    parameters:
    ...
    - in: "body"
      name: "body"
      description: "A JSON value representing a transaction. An example of the expected\
        \ schema can be found down here. The fields marked with an * means that\
        \ they are required."
      required: false
      schema:
        type: "string"  
      x-examples:
        application/json: "{foo: whatever, bar: whatever2}"

Cependant, cette valeur ne semble pas être récupérée par swagger-ui. J'ai essayé la version 2.2.10 et la dernière version 3.17.4, mais aucune des deux versions n'a utilisé la fonction x-examples du swagger.

Il existe quelques références pour x-example (celui qui est utilisé pour les paramètres non liés au corps) dans le fichier code de swagger-ui mais pas de correspondance pour x-examples . C'est que cela ne semble pas être supporté par swagger-ui pour le moment.

Si vous avez vraiment besoin que cet exemple de valeurs soit présent, votre meilleure option semble actuellement être de modifier la signature de votre méthode et d'utiliser un type de domaine dédié pour le paramètre body. Comme indiqué dans les commentaires, swagger détectera automatiquement la structure du type de domaine et imprimera des informations utiles dans swagger-ui :

Swagger-UI 2.2.10 with domain type info

4voto

E. Bavoux Points 155

Avez-vous essayé ce qui suit ?

@ApiModelProperty(
    value = "A JSON value representing a transaction. An example of the expected schema can be found down here. The fields marked with an * means that they are required.",
    example = "{foo: whatever, bar: whatever2}")

Passez une bonne journée

2 votes

Fonctionne parfaitement, mais seulement pour les types primitifs.

1voto

gce Points 51

Exemple Swagger.v3 Kotlin/Micronaut :

@Post("/get-list")
fun getList(
        @RequestBody(description = "Get list of ...",
                content = [Content(
                        mediaType = "application/json",
                        schema = Schema(implementation = RequestDTO::class),
                        examples = [ExampleObject(value = """
                            {
                                "pagination": {
                                    "page": 0,
                                    "perPage": 10
                                },
                                "filter": {
                                    "property_1": "string",
                                    "property_2": "string"
                                },
                                "sort": {
                                    "field": "property_1",
                                    "order": "DESC"
                                }
                            }
                        """)]
                )]) @Body request: RequestDTO): Response<SomeDTO> { ... }

0voto

Si vous utilisez swagger 2.9.2, les exemples ne fonctionnent pas. Ces annotations sont ignorées

protected Map<String, Response> mapResponseMessages(Set<ResponseMessage> from) {
  Map<String, Response> responses = newTreeMap();
  for (ResponseMessage responseMessage : from) {
    Property responseProperty;
    ModelReference modelRef = responseMessage.getResponseModel();
    responseProperty = modelRefToProperty(modelRef);
    Response response = new Response()
        .description(responseMessage.getMessage())
        .schema(responseProperty);
    **response.setExamples(Maps.<String, Object>newHashMap());**
    response.setHeaders(transformEntries(responseMessage.getHeaders(), toPropertyEntry()));
    Map<String, Object> extensions = new VendorExtensionsMapper()
        .mapExtensions(responseMessage.getVendorExtensions());
    response.getVendorExtensions().putAll(extensions);
    responses.put(String.valueOf(responseMessage.getCode()), response);
  }
  return responses;
}

Essayez d'utiliser swagger 3.0.0-Snapshot. Vous devez changer les dépendances maven comme ceci :

<dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>3.0.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>3.0.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-spring-webmvc</artifactId>
            <version>3.0.0-SNAPSHOT</version>
        </dependency>

et modifiez l'annotation de votre fichier de configuration Swagger comme suit : @EnableSwagger2WebMvc

1 votes

Ignore toujours les exemples/valeurs dans @ApiParam( value = "A JSON value", examples = @Example(value = @ExampleProperty(mediaType = MediaType.APPLICATION_JSON, value = "{foo : whatever, bar : whatever2}")))

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X