OptimisingEfficiency
OptimisingEfficiency

Reputation: 11

Swagger external file $ref using URI

Tech & versions:

Requirement:

"Deep nested referencing" with Swagger. As end result, I want to have a main swagger file, $ref an external file for a path parameter / response definition and the external file should then be able to $ref the child definitions within the same file.

So far:

I am using JSON.NET Schema library to run over our assembly and create swagger schemas in json format. These are then manually referenced from our main swagger.json file. I've had 2 results:

  1. Generate the external file WITHOUT $ref definitions, all inline, then when I $ref the external file from swagger.json, all is well in paradise.
  2. Generate the external file WITH $ref definitions, then when I $ref the external file from swagger.json, then none of the $ref in the external file can be resolved.

I'd like to get result 2 working.

For example, if I have the below two files, I want the "$ref": "#/definitions/Education" part to work. The swaggerSchemas.json output is what I get from the JSON.NET Schema generator. I've tried moving the "definitions" out of the "Person" to the root json wrapping of swaggerSchemas.json, but that also doesn't work. When I say "it doesn't work", I mean Swagger doesn't like it. The application dies on Swagger validation errors.

swagger.json

{
    "swagger": "2.0",
    "info": {
        "version": "0.0.1",
        "title": "ASDF"
    },
    "basePath": "/",
    "schemes": [
        "http",
        "https"
    ],
    "consumes": [
        "application/json",
        "application/octet-stream"
    ],
    "produces": [
        "application/json"
    ],
    "paths": {
        "/person": {
            "x-swagger-router-controller": "PersonController",
            "get": {
                "x-function": "find",
                "description": "Default Description",
                "tags": [
                    "gen"
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "schema": {
                            "$ref": "swaggerSchemas.json#/Person"
                        }
                    },
                    "default": {
                        "$ref": "#/responses/ErrorResponse"
                    }
                }
            }
        }
    }
}

swaggerSchemas.json

{
    "Person": {
        "definitions": {
            "education": {
                "type": "object",
                "properties": {
                  "highestQualification": {
                    "type": "string"
                  },
                  "extraData": {
                    "type": [
                      "string",
                      "number",
                      "integer",
                      "boolean",
                      "object",
                      "array"
                    ]
                  }
                },
                "required": [
                  "highestQualification",
                  "extraData"
                ]
            }
        },
        "type": "object",
        "properties": {
            "userId": {
                "type": "string"
            },
            "firstNames": {
                "type": "string"
            },
            "surname": {
                "type": "string"
            },
            "education": {
                "$ref": "#/definitions/Education"
            }
        }
    }
}

Is this behaviour, i.e. the "deep nesting $ref" available for Swagger 2.0?

If so, how do I accomplish this in JSON.NET Schema?

Upvotes: 1

Views: 8042

Answers (1)

Helen
Helen

Reputation: 97540

The structure of the swaggerSchemas.json file does not look valid:

{
  "Person": {
    "definitions": {
      "education": {
        "type": "object",
        ...
      }
    },

    "type": "object",
    ...
  }
}

Files containing multiple schemas should look as follows. The root tag name can be arbitrary, but it's common to use definitions.

{
  "definitions": {

    // "Education", not "education".
    // The letter case of the schema name must be the same as used in the $ref below.
    "Education": {
      "type": "object",
      ...
    },

    "Person": {
      "type": "object",
      "properties": {
        ...,
        "education": {
          "$ref": "#/definitions/Education"
        }
      }
    }

  }
}

Also, in the main file, change

"$ref": "swaggerSchemas.json#/Person"

to

"$ref": "swaggerSchemas.json#/definitions/Person"

to reflect the new node structure (definitions -> Person) in the swaggerSchemas.json file.

Upvotes: 2

Related Questions