user1031947
user1031947

Reputation: 6664

How to specify required properties on a requestBody object in an openApi project?

I have a yaml file for an openapi project that looks something like this...

components:

  schemas:

    Thing:
      type: object
      properties:
        id:
          type: integer
        prop1:
          type: string
        prop2:
          type: string
        prop3:
          type: string

paths:

  /things:
      summary: Create a thing
      requestBody:
        description: Thing object
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Thing'
        required: true

  /things/{id}:
    put:
      summary: Update a thing
      parameters:
      - name: id
        in: path
        description: Thing id
        schema:
          type: integer
      requestBody:
        description: Thing object
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Thing'
        required: true

I am wondering:

Is there a way to configure this so that when creating a "thing" the list of required properties is different than when "updating" a thing? (If I add the 'required' definition to components it affects all paths the same.)

For example, when creating a thing, prop1, prop2, and prop3 may all be required. But when updating a thing, only prop1 may be required.

Thanks!

Upvotes: 1

Views: 7290

Answers (1)

villapx
villapx

Reputation: 1883

You can accomplish this by using specific objects for "update" and "create", which inherit from Thing and impose the restrictions you need:

Thing:
  type: object
  required:
    - id
  additionalProperties: false
  properties:
    id:
      type: integer
    prop1:
      type: string
    prop2:
      type: string
    prop3:
      type: string

ThingUpdate:
  allOf:
    - $ref: '#/components/schemas/Thing'
  minProperties: 2

ThingCreate:
  allOf:
    - $ref: '#/components/schemas/Thing'
  required:
    - prop1
    - prop2
    - prop3

You then obviously need to modify your POST /things endpoint to take a ThingUpdate in the request body rather than just a Thing, and likewise for PUT /things/{id} and ThingCreate.

To accomplish the "update" validation, notice that in the Thing base object I specified additionalProperties: false and in ThingUpdate I specified minProperties: 2; that enforces that there need to be at least 2 properties in the "Thing", with no properties other than id, prop1, prop2 and prop3 (I assumed id is required, so I put it at the top of Thing).

For the "create" validation, I simply inherited from the Thing base class and specified that all of the non-id properties are required.


There's some redundancy here with the id parameter, since it's not needed for "create", and for "update" it's specified in the path rather than in the request body. You could remove id from the Thing base object and modify minProperties in ThingUpdate to instead be 1. Then, assuming you intend to add a separate GET /things endpoint where you want to retrieve all Things from your database or wherever, you can create a separate derived object ThingGet that includes allOf: Thing and adds the additional id property (under a properties: object).

Upvotes: 4

Related Questions