Search code examples
swaggerschemaresponseopenapi

variable in openapi 3.0 response schema


I have a legacy REST endpoint, which I would like to adress using openapi 3.0.

The Endpoint uses a path variable:

path: action/{action}s/

and also uses this path variable in the response schema like:

response in json:

{
  "name": "someName",
  "{action}": "someActionName",
  "{action}Id": 5
}

I couldn't find a explaination about this in the openapi guide. Is it possible to generate an openapi 3.0 spec with such a request? If yes, how would this example look like?

with this:

openapi: 3.0.0
info:
  title: My API
  version: 1.0.0
paths:
  /myaction/{action}s:
    get:
      summary: Get information for a specific action
      operationId: getActionInfo
      parameters:
        - name: action
          in: path
          required: true
          description: The name of the action
          schema:
            type: string
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  name:
                    type: string
                    description: The name of the response object
                  {action}:
                    type: string
                    description: The name of the action
                  {action}Id:
                    type: integer
                    description: The ID of the action
                required:
                  - name
                  - {action}
                  - {action}Id

in editor.swagger.io, I get a parser error in line 31. (The line with "{action}Id:")


Solution

  • It looks like you are trying to define logic within your schema. Openapi does not support the ability to define a key based upon a user defined parameter. At most, you could use openapi polymorphic responses to define a potential response based upon the user's input. For example:

    openapi: 3.0.0
    info:
      title: My API
      version: 1.0.0
    paths:
      /myaction/{action}s:
        get:
          summary: Get information for a specific action
          operationId: getActionInfo
          parameters:
            - name: action
              in: path
              required: true
              description: The name of the action
              schema:
                type: string
                enum:
                  - create
                  - delete
                  - update
                  - get
          responses:
            '200':
              description: OK
              content:
                application/json:
                  schema:
                    type: object
                    properties:
                      name:
                        type: string
                        description: The name of the response object
                    oneOf:
                      - $ref: '#/components/schemas/CreateAction'
                      - $ref: '#/components/schemas/DeleteAction'
                      - $ref: '#/components/schemas/UpdateAction'
                      - $ref: '#/components/schemas/GetAction'
                    required:
                      - name
    components:
      schemas:
        CreateAction:
          type: object
          required:
            - create
            - createId
          properties:
            create:
              type: string
              description: The name of the action
            createId:
              type: integer
              description: The ID of the action
        DeleteAction:
          required:
            - delete
            - deleteId
          type: object
          properties:
            delete:
              type: string
              description: The name of the action
            deleteId:
              type: integer
              description: The ID of the action
        UpdateAction:
          type: object
          required:
            - update
            - updateId
          properties:
            update:
              type: string
              description: The name of the action
            updateId:
              type: integer
              description: The ID of the action
        GetAction:
          type: object
          required:
            - get
            - getId
          properties:
            get:
              type: string
              description: The name of the action
            getId:
              type: integer
              description: The ID of the action
    

    This will allow you to define the response based upon the request. If going this route, I highly suggest using an enum as the action, to ensure only the proper response can be sent back.

    However, another option would be to change the response altogether. You could do something like this, and it would look cleaner and be more scalable.

    openapi: 3.0.0
    info:
      title: My API
      version: 1.0.0
    paths:
      /myaction/{action}s:
        get:
          summary: Get information for a specific action
          operationId: getActionInfo
          parameters:
            - name: action
              in: path
              required: true
              description: The name of the action
              schema:
                $ref: '#/components/schemas/Actions'
          responses:
            '200':
              description: OK
              content:
                application/json:
                  schema:
                    type: object
                    properties:
                      name:
                        type: string
                        description: The name of the response object
                      action:
                        type: object
                        required:
                          - name
                          - type
                          - id
                        properties:
                          type:
                            $ref: '#/components/schemas/Actions'
                          name:
                            type: string
                            description:  The name of the action
                          id:
                            type: integer
                            description: The ID of the action
    components:
      schemas:
        Actions:
          type: string
          description: The action to perform
          enum:
            - push
            - pull
            - punch
            - kick
    

    One thing of note here is that this is just an example. I don't recommend using enums in responses, as a change to your response could break any consumers of your api.