question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

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:
      ...

Issue Analytics

  • State:open
  • Created 7 years ago
  • Reactions:19
  • Comments:16 (7 by maintainers)

github_iconTop GitHub Comments

11reactions
DavidBiesackcommented, Mar 30, 2016

I very much like RAML’s use of traits for this. Let’s look there for design inspiration.

7reactions
casualjimcommented, Mar 30, 2016

@paulprogrammer we do this, because you basically want to share blocks of yaml right? This is why we chose yaml in the first place. I don’t think definition in the spec is strictly necessary

x-ResourceCommon: &ResourceCommon
    uuid:
      type: string
      description: uuid of the resource
    name:
      type: string
      description: name of the resource

paths:
'/blah/{id}':
    put:
      tags:
        - blah
      responses:
        '200': &RES_STATE
          description: request succeeded
          headers: &RESP_HEADERS
            X-Request-Id:
              description: the request id
              type: string
          schema:
            $ref: '#/definitions/ResourceState'
        '404': &RESP_ERROR
          description: resource not found
          headers: *RESP_HEADERS
          schema:
            $ref: "#/definitions/Error"
        '428': *RESP_ERROR
        default: *RESP_ERROR

definitions:
   ResourceGateway:
    description: An Internet Gateway resource type
    allOf:
      - "$ref": "#/definitions/Resource"
      - type:object
        properties:
          <<: *ResourceCommon
          id:
            type: string
            description: id of the InetGateway
          vpcId:
            type: string
            description: id of VPC

Read more comments on GitHub >

github_iconTop Results From Across the Web

What's the difference between a Mixin and a Trait?
This question asks for a list of languages that have traits and mixins and a list of properties that those implementations have.
Read more >
Mixin and traits. Mixin, the Diamond problem, inheritance
Mixins are synonymous with abstract base classes. Inheriting from a mixin is not a form of specialization but is rather a means of...
Read more >
Traits vs Mixins - Steve Fenton
Traits are conceptually the same as mixins, allowing you to add shared methods to your class; but they are stateless. When you specify...
Read more >
Mixins or Traits? That is the Question - 10Pines | Blog
A mixin is an abstract subclass that may be used to specialize the behavior of a variety of parent classes. What does this...
Read more >
Class Composition with Mixins | Tour of Scala
Mixins are traits which are used to compose a class. Scala 2; Scala 3.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found