Reputation: 6117
Let's say I have some simple Order > OrderLines > Product Data Model in an OpenAPI document. The Components part would look like this:
components:
schemas:
Order:
required:
- orderId
properties:
orderId:
type: integer
orderlines:
type: array
items:
$ref: '#/components/schemas/OrderLine'
OrderLine:
required:
- orderLineId
- product
- price
properties:
orderLineId:
type: integer
product:
$ref: '#/components/schemas/Product'
price:
type: integer
Product:
required:
- productId
- name
x-keys:
- productId
properties:
productId:
type: integer
name:
type: string
When building a path to define an api to get a specific OrderLine on an Order, this would look like this:
paths:
/orders/{orderId}/orderlines/{orderLineId}:
get:
operationId: getOrderLine
parameters:
- in: path
name: orderId
schema:
type: integer
required: true
- in: path
name: orderLineId
schema:
type: integer
required: true
Now, the defined orderId parameters actually refers to the orderId property of the Order Component. And the same goes for parameter orderLineId which refers to the orderLineId property of Component OrderLine.
So is it possible to actually refer to these properties in the parameter definition instead of duplicating the type information of the properties?
I mean is it somehow possible to do something like this:
paths:
/orders/{orderId}/orderlines/{orderLineId}:
get:
operationId: getOrderLine
parameters:
- in: path
name: orderId
$ref: #components/schemas/Order/properties/orderId
required: true
- in: path
name: orderLineId
$ref: #components/schemas/OrderLine/properties/orderLineId
required: true
Upvotes: 2
Views: 3543
Reputation: 97677
First of all, always add type: object
to your object definitions; the properties
keyword alone is not enough to indicate the object type. The type
is not inferred from other keywords, and no type
actually means "any type".
As for your question - sure, it's possible to $ref
individual property definitions. Your example is almost correct, you just need to:
Put the $ref
inside the parameter schema
.
Replace #components
with #/components
.
Enclose the reference values (#/components/...
) in quotes to prevent them from being parsed as YAML comments.
paths:
/orders/{orderId}/orderlines/{orderLineId}:
get:
operationId: getOrderLine
parameters:
- in: path
name: orderId
schema:
$ref: '#/components/schemas/Order/properties/orderId'
required: true
- in: path
name: orderLineId
schema:
$ref: '#/components/schemas/OrderLine/properties/orderLineId'
required: true
However, referencing property definitions is uncommon, and some tools may have problems handling such references. It's best to define separate schemas for all definitions you want to $ref
:
components:
schemas:
OrderId: # <-------
type: integer
OrderLineId: # <-------
type: integer
Order:
type: object
required:
- orderId
properties:
orderId:
$ref: '#/components/schemas/OrderId' # <-------
...
OrderLine:
type: object
required:
- orderLineId
- product
- price
properties:
orderLineId:
$ref: '#/components/schemas/OrderLineId' # <-------
...
paths:
/orders/{orderId}/orderlines/{orderLineId}:
get:
operationId: getOrderLine
parameters:
- in: path
name: orderId
schema:
$ref: '#/components/schemas/OrderId' # <-------
required: true
- in: path
name: orderLineId
schema:
$ref: '#/components/schemas/OrderLineId' # <-------
required: true
Upvotes: 4