learn.openapis.org icon indicating copy to clipboard operation
learn.openapis.org copied to clipboard

Improve examples

Open KES777 opened this issue 7 years ago • 8 comments

None of examples do not provide put example

KES777 avatar Apr 24 '18 13:04 KES777

@KES777 There's not really any difference between PUT and POST from the perspective of the OpenAPI description. Is there some specific thing you are looking for an example to demonstrate?

darrelmiller avatar Apr 24 '18 14:04 darrelmiller

No. Just for purpose of completeness

KES777 avatar Apr 24 '18 18:04 KES777

Today I have good question. and can describe specific thing which is worth to demonstrate. For example we have next thing:

components:
  schemas:
    Country:
      type: object
      required:
        - id
        - code
      properties:
        id:
          type: integer
          readOnly: true
        code:
          type: string
       name:
         type: string

To create new country I have next path:

paths:
  /countries:
    post:
      summary: Create a country
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Country'

Thus to create country we send next json:

{
    code: 'UA',
}

It is OK. Only code is required, id is readonly

But when we update this country we can send one of: code or name or both.

The schema may looks like:

paths:
  /countries:
    put:
      summary: Update a country
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Country'

But this will restrict us to send next API request PUT /api/countries/1:

{
    name: 'some name',
}

Which will cause validation error:

`code` field is required

It seems I should define it via anyOf. Is this correct decision?

paths:
  /countries:
    put:
      summary: Update a country
      requestBody:
        required: true
        content:
          application/json:
            schema:
                   anyOf: 
                        - $ref: '#/components/schemas/Country'

But this also requires code to be present in request.

How to describe: expect any of properties in Country?

KES777 avatar Jun 01 '18 16:06 KES777

@KES777, If I understand correctly, you want to have different constraints on the POST request, where you're creating a new Country, vs. the PUT request, where you're updating an existing country.

I think you can accomplish this with separate schema objects, defined like this:

components:
  schemas:
    # Base type for a Country, with minimal constraints
    BaseCountry:
      type: object
      properties:
        id:
          type: integer
          readOnly: true
        code:
          type: string
        name:
          type: string

    # Country with at least one known property, used for PUT or PATCH requests.
    NonEmptyCountry:
      allOf:
      - $ref: "#/components/schemas/BaseCountry"
      # require at least one known property value.
      minProperties: 1
      additionalProperties: false
      # additionalProperties doesn't have visibility into the inherited properties,  
      # so re-declare these:
      properties:
        id:
        name:
        code:

    # Country object in its complete, steady state
    Country:
      allOf:
      - $ref: "#/components/schemas/NonEmptyCountry"
      required:
      - id

Your put request can use NonEmptyCountry, which must have at least one of the known properties, excluding id which is readOnly.

Your post request can use Country or NonEmptyCountry, which are equivalent in the request context.

Responses that include an object representation should use Country, which requires id.

tedepstein avatar Jun 02 '18 15:06 tedepstein

@tedepstein Thanks. You understand correct.

KES777 avatar Jun 03 '18 20:06 KES777

@tedepstein: I should not redeclare id for NonEmptyCountry because it must be excluded

KES777 avatar Jun 08 '18 10:06 KES777

Here is my variant of schema. I did it slightly differently. Maybe will be useful for others

api-v1.yaml.txt

KES777 avatar Jun 09 '18 11:06 KES777

We are moving supplementary examples to the learn.openapis.org site, so I am going to transfer this issue so it's easier to see what issues are for the separate examples and what are for the examples embedded in the spec. See this issue for the decision:

  • OAI/OpenAPI-Specification#3854

handrews avatar May 30 '24 22:05 handrews