6

I want to split my paths (which are quite many) more easily into their own files.

Let's say I've got two major paths /user and /anotherPath with several subpaths. Now I've got an OpenApi spec file, whose paths are being referenced to an index file which holds references to each paths. Defining EVERY path with its' reference works, but is clumsy to write.

I want something like this:

openapi.json

{
...
  "paths": {
    "$ref": "paths/index.json"
  }
...
}

paths/index.json

{
  "/user": { // and everything that comes after user, e.g. /user/{userId}
    "$ref": "./user-path.json"
  },
  "/anotherPath": {  // and everything that comes after anotherPath, e.g. /anotherPath/{id}
    "$ref": "./anotherPath-path.json"
  }
}

paths/user-path.json

{
  "/user": {
    "get": {...}
  },
  "/user/{userId}": {
    "get": {...}
  }
}

paths/anotherPath-path.json

{
  "/anotherPath": {
    "get": {...}
  },
  "/anotherPath/{id}": {
    "get": {...}
  }
}

This way, whenever I add another path to /user or /anotherPath, I can simply edit their respective path file, e.g. paths/user-path.json.

EDIT1: Apparently, this topic is being discussed already.. For anyone interested: https://github.com/OAI/OpenAPI-Specification/issues/417 . By the way, I know that a $ref is not valid for the paths Object, but once figuring out how to properly split, this may not be necessary anymore.

prohit
  • 609
  • 1
  • 6
  • 18
  • Related: [How to use $ref to reference a path from another OpenAPI file?](https://stackoverflow.com/q/58909124/113116), [Can't setup swagger - Cannot read property 'parameters' of undefined](https://stackoverflow.com/q/60271342/113116) – Helen Apr 21 '20 at 13:45

1 Answers1

13

OpenAPI does not have a concept of sub-paths / nested paths, each path is an individual entity. The paths keyword itself does not support $ref, only individual paths can be referenced.

Given your user-path.json and anotherPath-path.json files, the correct way to reference path definitions is as follows:

{
  ...
  "paths": {
    "/user": {
      "$ref": "paths/user-path.json#/~1user"  // ~1user is /user escaped according to JSON Pointer and JSON Reference rules
    },
    "/user/{id}": {
      "$ref": "paths/user-path.json#/~1user~1%7Bid%7D"  // ~1user~1%7Bid%7D is /user/{id} escaped 
    },
    "/anotherPath": {
      "$ref": "paths/anotherPath-path.json#/~1anotherPath"  // ~1anotherPath is /anotherPath escaped
    },
    "/anotherPath/{id}": {
      "$ref": "paths/anotherPath-path.json#/~1anotherPath~1%7Bid%7D"  // ~1anotherPath~1%7Bid%7D is /anotherPath/{id} escaped
    }
  }
  ...
}

YAML version:

paths:
  /user:
    $ref: "paths/user-path.json#/~1user"
  /user/{id}:
    $ref: "paths/user-path.json#/~1user~1%7Bid%7D"
  /anotherPath:
    $ref: "paths/anotherPath-path.json#/~1anotherPath"
  /anotherPath/{id}:
    $ref: "paths/anotherPath-path.json#/~1anotherPath~1%7Bid%7D"


If you want to use $ref in arbitrary places (other than where OAS allows $refs), you'll have to pre-process your definition using a parser/tool that can resolve arbitrary $refs; this will give you a valid OpenAPI file that can be used with OpenAPI-compliant tools. One such pre-processing tool is json-refs, you can find an example of pre-processing here.

Helen
  • 87,344
  • 17
  • 243
  • 314
  • This is my current setup, but I find it redundant to write the exact path 2 times: 1 in `paths` and 1 in `user-path.json`. Guess I will have to wait for `paths` to accept something like [patternproperties](https://json-schema.org/understanding-json-schema/reference/object.html#pattern-properties) – prohit Apr 21 '20 at 12:56
  • Alternatively, you can use your example with `$ref` directly under `paths`, but use a JSON $ref resolver (not OpenAPI resolver) to bundle everything into a single file - see the updated answer. – Helen Apr 21 '20 at 13:47
  • Actually, e.g. the Swagger Previewer renders `$ref` directly in `paths` pretty well. I'm using a VS Code + Swagger Previewer extension and that works well. Only splitting of `Path Item Objects` for easier usage with many (sub)routes is not supproted. I will look into manually pre-processing, thanks. – prohit Apr 22 '20 at 05:11