Swagger/OAS Schema design discussion

64 Views Asked by At

Background:

We support an API guide directory where we document and show the different web services present in our system. There are many containers that group related services and few services have a common schema/model. For ex, ignore the identifier as this is an excample create a person - POST - [name, email, age] get all persons - GET - list of [name, email, age]

The 2 calls above have the same model,

        "name" : {
          "type" : "string",
          "description" : "name of the persion"
        },
        "email" : {
          "type" : "string",
          "description" : "user email id",
          "example" : "[email protected]"
        },
        "age" : {
          "type" : "integer",
          "description" : "user age",
          "example" : 20
        }

Question:

We have been using the same schema against both GET/POST calls so far, and now we want to add additional validations that may exist on fields, for example, name cannot contain numbers..

        "name" : {
          "type" : "string",
          "description" : "name of the persion",
          **"validation" : "name cannot contain numbers"**
        },
        "email" : {
          "type" : "string",
          "description" : "user email id",
          "example" : "[email protected]"
        },
        "age" : {
          "type" : "integer",
          "description" : "user age",
          "example" : 20
        }

As you can see this validation makes sense on POST requests only and not on get requests,

Solutions:

So, what is a good design in this case?

  1. Have separate snippets for GET and POST?(one without the validation and one with))
  2. Keep the validation and maintain only one schema and let user see the extra field?

Any industry standards documented? any experiences/ examples? Just interested in getting some thoughts!

Opening discussion to learn and discuss what a better design would be for a problem many might have faced or will face.

1

There are 1 best solutions below

1
On

I would keep the schema that has the common elements, then create other schemas that define the additional elements.

So if your common model is defined like

components:
  schemas:
    common:
      type: object
      properties:
        foo:
          type: string

you can create a secondary schema that references that one and adds other elements, even to pre-existing properties.

components:
  schemas:
    common:
      type: object
      properties:
        foo:
          type: string
    common-with-validation:
      allOf:
        - $ref: #/components/schemas/common
        - properties:
            foo:
              maxLength: 50

In this document, the common-with-validation schema starts with the common schema and adds a maxLength to the existing requirements on the foo property. I don't need to re-specify that the payload is an object or that foo is a string because the reference already does those things.