mvermand
mvermand

Reputation: 6117

OpenAPI Path Parameters referencing Component Properties

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

Answers (1)

Helen
Helen

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:

  1. Put the $ref inside the parameter schema.

  2. Replace #components with #/components.

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

Related Questions