Skip to content

Traits or Mixins #38

@paulprogrammer

Description

@paulprogrammer

I would like to be able to add something like traits or mixins to operations. For instance, if I have a GET /foo that returns a list of foo objects I could mark it as "pageable" (assuming I've defined a pageable trait) that would include the pageSize and pageNumber query parameters, and force a "pagination" element in the payload object.

This would allow us to utilize reuse concepts to provide a semantic view of the endpoint definitions.

traits:
  pagable:
    parameters:
      - name: pageSize
        in: query
        type: number
        required: false
        default: 10
      - name: pageNumber
        in: query
        type: number
        required: false
        default: 1
    response:
      200:
        schema:
          pagination:
            $ref: "#/definitions/PaginationFragment"
mixins:
  metadata:
    schema:
      metadata:
        $ref: "#/definitions/MetadataFragment"
paths:
  /foo:
    get:
      description: search for foo resources
      is: 
        - pagable
      parameters:
        - name: q
          in: query
          type: string
          required: true
      responses:
        200:
          has:
            - metadata
          schema:
            type: object
            FooItems:
              array:
                items:
                  $ref: '#/definitions/FooItem'

This would result in a long-form definition as:

paths:
  /foo:
    get:
      description: search for foo resources
      parameters:
        - name: pageSize
          in: query
          type: number
          required: false
          default: 10
        - name: pageNumber
          in: query
          type: number
          required: false
          default: 1
        - name: q
          in: query
          type: string
          required: true
      responses:
        200:
          schema:
            type: object
            FooItems:
              metadata:
                $ref: "#/definitions/MetadataFragment"
              pagination:
                $ref: "#/definitions/PaginationFragment"
              array:
                items:
                  $ref: '#/definitions/FooItem'

This is obviously silly if you have only one pageable endpoint, but assuming you had many resources that were listable, you could define how pagination works across the entire suite in a DRY manner.

Open questions: I defined "is" for traits on an operation, and "has" as mixins for an object, but the resolution rules are the same. Not sure if this is really a good practice.

Other uses: Consider if there are commonly used headers -- you might have a mixin for the path object that contains headers that are merged with the list of headers defined by the implementation:

mixins:
  commonHeaders:
    parameters:
      - name: x-really-important
        in: header
        type: string
        required: true

paths:
  /bar/{barId}:
    has:
      - commonHeaders
    parameters:
      - name: barId
        in: path
        required: true
        type: number
    get:
      ...

This would resolve to:

paths:
  /bar/{barId}:
    parameters:
      - name: x-really-important
        in: header
        type: string
        required: true
      - name: barId
        in: path
        required: true
        type: number
    get:
      ...

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions