JSON Pointer inside JSON document: how to express in YAML?

1.3k Views Asked by At

I'm defining the Swagger specification of a REST service to be implemented. Since the response document represents a tree-like structure where several nodes repeat multiple times, I'd like to define them in the beginning of a document and then reference them by means of JSON Pointer notation.

So the response document should look like this:

{
    "definitions": {
        "organizations": [
            { "id": 101, "name": "Org 1" },
            ...
        ],        
        "clusters": [
            { "id": 201, "name": "Cluster 1" },
            ...
        ],        
        "plants": [
            { "id": 301 }
        ]
    },    
    "plants_hierarchy": {
        "relations": [
            {
                "cluster": { "$ref", "#/definitions/clusters/1" },
                "organization": { "$ref", "#/definitions/organizations/123" },                    
                "plants": [
                    { "$ref": "#/definitions/plants/234" },
                    ...
                ]
            },
            ...
        ]
    }
}

The plant objects inside #/plants_hierarchy/relations/plants should be represented as JSON Pointer and not as the original objects in order to keep the size of the document small.

My question is how should I express the JSON Pointer in the Swagger YAML document?

2

There are 2 best solutions below

0
On BEST ANSWER

YAML provides anchors and aliases, which cover your use-case exactly:

definitions:
  organizations:
    - &my_organization
      id: 101
      name: Org 1
  clusters:
    - &my_cluster
      id: 201
      name: Cluster 1
  plants:
     - &my_plant
       id: 301 
plants_hierarchy:
  relations:
    - cluster: *my_cluster
      organization: *my_organization
      plants:
        - *my_plant
0
On

First of all, why don't you just include the data inline? Using JSON References/JSON Pointers in actual API responses is a rather unusal scenario, and it would require your API clients to use a JSON Reference resolution library to calculate those references. Most languages/frameworks have JSON libraries, but JSON Reference resolution libraries are rare. If all data is inline, then it's trivial to access it - e.g. simply use response.plants_hierarchy.relations[0].cluster.name. But hiding data behind JSON References makes things a lot more complicated for the clients.

Anyway, if you are sure this is what you want to do, then the $ref property can be defined a simple string property, possibly with a pattern.

swagger: '2.0'
...

definitions:
  JsonReference:
    type: object
    properties:
      '$ref':
        type: string
        pattern: '^#'
        example: '#/definitions/something/1'

  Relation:
    type: object
    properties:
      cluster:
        $ref: '#/definitions/JsonReference'
      organization:
        $ref: '#/definitions/JsonReference'
      plants:
        type: array
        items:
          $ref: '#/definitions/JsonReference'