|
| 1 | +[Source](https://github.com/OAI/OpenAPI-Specification/issues/1843) |
| 2 | + |
| 3 | + |
| 4 | +I'm opening this issue simply as a place to collect some ideas about how the concepts of [Overlays](#1722) and [Traits](#613) might be brought together. |
| 5 | + |
| 6 | +In both proposals, I think the key notion is a "fragment", which I would describe as: a "sparse" sub-object of an OpenAPI definition. In the Overlay proposal, a fragment is the `value` of an "Update Object" and has a type of `any`. |
| 7 | + |
| 8 | +I think fragments -- which I would like to call "mixins" -- can have a more well-defined structure than just `any`. If we use the `discriminator` approach already present in OpenAPI for "mixins", we can require (and validate) conformance to a particular structure. In particular, we can require a mixin to be a "sparse" form of any well-defined OpenAPI object, e.g. Operation, Response, Parameters, or even the whole OpenAPI definition. |
| 9 | + |
| 10 | +Mixins could be defined as just another flavor of "component". So |
| 11 | +``` |
| 12 | +components: |
| 13 | + mixins: |
| 14 | + pagable: |
| 15 | + type: operation << so what follows should validate as a "sparse"* OpenAPI Operation object |
| 16 | + < pageable parameters and response props in #613 > |
| 17 | +``` |
| 18 | + |
| 19 | +Note *: "sparse" here means all props are optional |
| 20 | + |
| 21 | +Mixins could then be included effectively anywhere in the API doc by reference: |
| 22 | +``` |
| 23 | + $mixin: "/components/mixin/pageable" |
| 24 | +``` |
| 25 | + |
| 26 | +By virtue of the mixin type, it could be validated as allowed or not allowed at the point it is referenced. |
| 27 | + |
| 28 | +Now Overlays can become simply a mechanism for inserting mixins and mixin references into an API document. The JMESPath mechanism of overlays still provide the ability to apply a single update to multiple target objects using wildcards, but that update would now be expressed as simply adding a "mixin" to each of the target objects. |
| 29 | + |
| 30 | +These are just strawman ideas and I do not claim to have thought them through any detail, but I hope they can serve as useful seeds for discussion. |
| 31 | + |
| 32 | +### Examples |
| 33 | + |
| 34 | +Mixins are a recasting of "Traits" as described in #613. Here's how I imagine mixins could be used to apply a "pageable" trait to operations. |
| 35 | + |
| 36 | +The "pageable" mixin would be defined in the `components / mixins` section of the API doc: |
| 37 | + |
| 38 | +``` |
| 39 | +components: |
| 40 | + mixins: |
| 41 | + pagable: |
| 42 | + type: operation |
| 43 | + content: |
| 44 | + parameters: |
| 45 | + - name: pageSize |
| 46 | + in: query |
| 47 | + type: number |
| 48 | + required: false |
| 49 | + default: 10 |
| 50 | + - name: pageNumber |
| 51 | + in: query |
| 52 | + type: number |
| 53 | + required: false |
| 54 | + default: 1 |
| 55 | + response: |
| 56 | + 200: |
| 57 | + schema: |
| 58 | + type: object |
| 59 | + pagination: |
| 60 | + $ref: "#/definitions/PaginationFragment" |
| 61 | +``` |
| 62 | + |
| 63 | +and an operation would "apply" the "pageable" mixin with a $mixin property, as follows: |
| 64 | +``` |
| 65 | +paths: |
| 66 | + /foo: |
| 67 | + get: |
| 68 | + description: search for foo resources |
| 69 | + $mixin: |
| 70 | + - pagable |
| 71 | + parameters: |
| 72 | + - name: q |
| 73 | + in: query |
| 74 | + type: string |
| 75 | + required: true |
| 76 | + responses: |
| 77 | + 200: |
| 78 | + schema: |
| 79 | + type: object |
| 80 | + FooItems: |
| 81 | + array: |
| 82 | + items: |
| 83 | + $ref: '#/definitions/FooItem' |
| 84 | +``` |
| 85 | + |
| 86 | +The application of the mixin to the operation would yield on operation like: |
| 87 | +``` |
| 88 | +paths: |
| 89 | + /foo: |
| 90 | + get: |
| 91 | + description: search for foo resources |
| 92 | + parameters: |
| 93 | + - name: q |
| 94 | + in: query |
| 95 | + type: string |
| 96 | + required: true |
| 97 | + - name: pageSize |
| 98 | + in: query |
| 99 | + type: number |
| 100 | + required: false |
| 101 | + default: 10 |
| 102 | + - name: pageNumber |
| 103 | + in: query |
| 104 | + type: number |
| 105 | + required: false |
| 106 | + default: 1 |
| 107 | + responses: |
| 108 | + 200: |
| 109 | + schema: |
| 110 | + type: object |
| 111 | + FooItems: |
| 112 | + array: |
| 113 | + items: |
| 114 | + $ref: '#/definitions/FooItem' |
| 115 | + pagination: |
| 116 | + $ref: "#/definitions/PaginationFragment" |
| 117 | +``` |
0 commit comments