web-dev-qa-db-fra.com

Réutiliser un modèle avec différentes propriétés requises

J'ai un chemin qui utilise des modèles complexes avec des propriétés presque identiques pour chaque méthode http. Le problème est que je veux définir certaines propriétés requises pour la requête PUT et POST, alors qu'aucune propriété n'est requise dans la réponse GET (car le serveur renvoie toujours toutes les propriétés, comme indiqué ailleurs dans la documentation).

J'ai créé une API de chat simple pour démontrer ce que j'ai essayé. L'idée est que, pour la réponse GET, le modèle de réponse ne comporte pas d'indication requise, mais que la requête de PUT doit avoir un nom pour le chat.

swagger: "2.0"

info:
  title: "Cat API"
  version: 1.0.0

paths:
  /cats/{id}:
    parameters:
      - name: id
        in: path
        required: true
        type: integer
    get:
      responses:
        200:
          description: Return a cat
          schema:
            $ref: "#/definitions/GetCat"
    put:
      parameters:
        - name: cat
          in: body
          required: true
          schema:
            $ref: "#/definitions/PutCat"
      responses:
        204:
          description: Cat edited

definitions:
  Cat:
    type: object
    properties:
      name:
        type: string
  GetCat:
    allOf:
      - $ref: "#/definitions/Cat"
    properties:
      id:
        type: integer
  PutCat:
    type: object
    required:
      - name
    properties:
      $ref: "#/definitions/Cat/properties"

Swagger Editor indique qu'il s'agit d'une spécification valide, mais que name est défini comme requis pour GET et PUT. Il en va de même avec l'interface utilisateur Swagger.

J'ai aussi essayé la version suivante de PutCat:

PutCat:
  type: object
  required:
    - name
  allOf:
    - $ref: "#/definitions/Cat"

Mais maintenant tout est optionnel.

Je ne peux pas comprendre cela. Y a-t-il un moyen de le faire correctement?

MODIFIER:

En tant que Helen correctement mentionné, je peux utiliser readOnly pour résoudre ce cas particulier avec GET et PUT.

Mais disons que j'ajoute la propriété breed qui doit être fournie (en plus de la propriété name) pour PUT. Ensuite, j'ajoute la méthode PATCH, qui peut être utilisée pour mettre à jour breed ou name pendant que l'autre reste inchangé, et je ne souhaite définir aucune de celles-ci comme requis.

16
NotNone

Dans votre exemple, vous pouvez utiliser un seul modèle pour GET et POST/PUT, les propriétés utilisées uniquement dans la réponse GET étant marquées par readOnly. De la spec :

readOnly

Déclare la propriété comme "lecture seule". Cela signifie qu'il PEUT être envoyé dans le cadre d'une réponse mais NE DOIT PAS être envoyé dans le cadre de la demande. Les propriétés marquées comme étant en lecture seule ne doivent pas figurer dans la liste requise du schéma défini. La valeur par défaut est false.

La spécification ressemblerait à ceci:

    get:
      responses:
        200:
          description: Return a cat
          schema:
            $ref: "#/definitions/Cat"
    put:
      parameters:
        - name: cat
          in: body
          required: true
          schema:
            $ref: "#/definitions/Cat"
      responses:
        204:
          description: Cat edited

definitions:
  Cat:
    properties:
      id:
        type: integer
        readOnly: true
      name:
        type: string
      breed:
        type: string
    required:
      - name
      - breed

Cela signifie que vous devez mettre les name et breed:

{
  "name": "Puss in Boots",
  "breed": "whatever"
}

et GET /cats/{id} doit renvoyer les name et breed et peut également renvoyer les id:

{
  "name": "Puss in Boots",
  "breed": "whatever",
  "id": 5
}
21
Helen

J'ai eu un problème similaire. Il s'est avéré que mon indentation était erronée ... La syntaxe suivante devrait fonctionner

PutCat:
  allOf:
    - $ref: "#/definitions/Cat"
    - type: object
      required: [name]
1
AlexGordon