# OpenAPI definition resolver Resolves [JSON-References](https://tools.ietf.org/html/draft-pbryan-zyp-json-ref-03) (`$ref`) with the values they point to inside OpenAPI definition. Our API can work with either OpenAPI Specification represented as [POJO](https://en.wikipedia.org/wiki/Plain_old_Java_object) or as URL that points to the OpenAPI definition file. > *__Note:__ We'll demonstrate the code examples on objects that doesn't represent OpenAPI Specification, to keep the examples short* ### POJO usage ```js import SwaggerClient from 'swagger-client'; const pojoDefinition = { a: 1, b: { $ref: '#/a', } }; SwaggerClient.resolve({ spec: pojoDefinition }); /** * Promise({ * spec: { * "a": 1, * "b": 1 * }, * errors: [] * }) */ ``` ### URL usage Provided url will be resolved as OpenAPI definition. Then the algorithm works recursively and resolves all `JSON-References` inside the resolved OpenAPI definition. ```js import SwaggerClient from 'swagger-client'; SwaggerClient.resolve({ url: 'https://raw.githubusercontent.com/swagger-api/swagger-petstore/main/src/main/resources/openapi.yaml'}); /** * Promise({ * spec: ...resolved pet store..., * errors: [] * }) */ ``` > *__Note:__ you can provide `Swagger.resolve` both `spec` and `url` options. In that case `spec` will always be preferred and `url` option will be ignored.* #### Authentication When JSON-References points to a remote document protected by authentication, `requestInterceptor` option can be used to provide request authentication (e.g. by setting `Authentication` header). ```js import SwaggerClient from 'swagger-client'; const requestInterceptor = request => { if (request.loadSpec) { request.headers['Authorization'] = 'Bearer Asdf1234ThisIsMyToken'; } return request; }; SwaggerClient.resolve({ url: 'https://raw.githubusercontent.com/swagger-api/swagger-petstore/main/src/main/resources/openapi.yaml', requestInterceptor, }); ``` > *__Note:__ Notice how we use [loadSpec](http-client.md#loading-specification) Request property to determine if the intercepted request was made to fetch the OAS definition.* #### Errors Resolver can also produce errors on various problems inside OpenAPI definition. One of those problems can be invalid `JSON-Reference`. ```js import SwaggerClient from 'swagger-client'; const pojoDefiniton = { a: 1, b: { $ref: 1, } }; SwaggerClient.resolve({ spec: pojoDefiniton }); /** * Promise({ * "spec": { * "a": 1, * "b": { * "$ref": 1 * } * }, * "errors": [ * { * "message": "$ref: must be a string (JSON-Ref)", * "$ref": 1, * "fullPath": [ * "b", * "$ref" * ] * } * ] * }) */ ``` #### Alternate API ##### Resolve during instantiation Along with calling `resolve` statically from a `SwaggerClient` class, resolution can happen during `SwaggerClient` class instantiation. **POJO usage** ```js import SwaggerClient from 'swagger-client'; const pojoDefinition = { a: 1, b: { $ref: '#/a', } }; new SwaggerClient({ spec: pojoDefinition }).then(swaggerClient => { swaggerClient.spec; swaggerClient.originalSpec; swaggerClient.errors; }); ``` **URL usage** ```js import SwaggerClient from 'swagger-client'; new SwaggerClient('https://raw.githubusercontent.com/swagger-api/swagger-petstore/main/src/main/resources/openapi.yaml').then(swaggerClient => { swaggerClient.spec; swaggerClient.errors; }); ``` or ```js import SwaggerClient from 'swagger-client'; new SwaggerClient({ url: 'https://raw.githubusercontent.com/swagger-api/swagger-petstore/main/src/main/resources/openapi.yaml' }).then(swaggerClient => { swaggerClient.spec; swaggerClient.errors; }); ``` ##### Re-resolve the definition It's possible (as a convenience) to re-resolve your definition from `resolve` instance method. ```js import SwaggerClient from 'swagger-client'; const pojoDefinition = { a: 1, b: { $ref: '#/a', } }; new SwaggerClient({ spec: pojoDefinition }) .then(swaggerClient => swaggerClient.resolve()) // definition will be re-resolved again .then(swaggerClient => { swaggerClient.spec; swaggerClient.originalSpec; swaggerClient.errors; }); ``` #### Options Along with `spec` and `url`, there are other options that controls the resolution algorithm behavior. Type notations are formatted like so: - `String=""` means a String type with a default value of `""`. - `String=["a"*, "b", "c", "d"]` means a String type that can be `a, b, c, or d`, with the `*` indicating that `a` is the default value. Option | Description --- | --- `fetch` | `Function=Http`. Alias for `http`. The option is part of API due to compatibility reasons. `http` | `Function=Http`. If provided this function will be used as primary HTTP fetch mechanism for resolution. The provided function must return a `Promise` and must be compatible with our [HTTP Client](http-client.md). `mode` | `String=["nostrict", "strict"]`. If `strict`, don't process `allOf` JSON-References. `allowMetaPatches` | `Boolean=true`. Allows adding `.meta` patches, which include adding `$$ref`s to the resolved definition. `$$ref` is a meta information created from the original JSON Reference.

**Original definition:**

`{"a":{"val":1},"b":{"$ref":"#/a"}}`

**Resolved definition:**

`{"a":{"val":1},"b":{"val":1,"$$ref":"#/a"}}` `pathDiscriminator` | `Array=[]`. Example value can be e.g. `['components', 'schemas']`. This tells the resolver to only resolve all `Json-Reference` on this path and leave the rest untouched. Can be used for lazy resolution. `modelPropertyMacro` | `Function=null`. If provided, accepts a `property` object e.g. `{type: 'integer', format: 'int64' }` and computes a default value. That computed value is then assigned into original `property` object under the key `default`; `{type: 'integer', format: 'int64', default: 1 }` `parameterMacro` | `Function=null`. If provided, accepts a `parameter` object e.g. `{ name: 'offset', in: 'query' }` and computes a default value. That computed value is then assigned into original `parameter` object under the key `default`; `{ name: 'offset', in: 'query', default: 1 }` `requestInterceptor` | `Function=identity`. Intercepts and possibly transform a request before it is handled. `responseInterceptor` | `Function=identity`. Intercepts and possibly transform a response before it is handled. `skipNormalization` | `Boolean=false`. Normalization creates unique operationIds when explicit operationIds are duplicates, and preserve originals. `useCircularStructures` | `Boolean=false`. Prevents circular values from being constructed, unless you specifically want that to happen. If set to `false`, just leave the references unresolved. `baseDoc` | `String=null`. If provided in the form of `URL`, will be able to resolve circular `JSON-References`. #### Sub-Tree resolver When working with a large JSON OpenAPI definition, it's often convenient to resolve `JSON-References` in only part of the JSON OpenAPI definition tree. Our sub-tree resolver does exactly that. ```js import SwaggerClient from 'swagger-client'; const pojoDefinition = { a: 1, b: { $ref: '#/a', } }; SwaggerClient.resolveSubtree(pojoDefinition, ['b']); /** * Promise({ * spec: 1, * errors: [], * } */ ``` > *__Note:__ third argument is optional and if provided it must be of the shape of `Options` documented below.* Option | Description --- | --- `returnEntireTree` | `Boolean=false`. If set to true, returns only resolved part of OpenAPI definition tree determined by `path` (second argument). `modelPropertyMacro` | `Function=null`. If provided, accepts a `property` object e.g. `{type: 'integer', format: 'int64' }` and computes a default value. That computed value is then assigned into original `property` object under the key `default`; `{type: 'integer', format: 'int64', default: 1 }` `parameterMacro` | `Function=null`. If provided, accepts a `parameter` object e.g. `{ name: 'offset', in: 'query' }` and computes a default value. That computed value is then assigned into original `parameter` object under the key `default`; `{ name: 'offset', in: 'query', default: 1 }` `requestInterceptor` | `Function=identity`. Intercepts and possibly transform a request before it is handled. `responseInterceptor` | `Function=identity`. Intercepts and possibly transform a response before it is handled. `useCircularStructures` | `Boolean=false`. Prevents circular values from being constructed, unless you specifically want that to happen. If set to `false`, just leave the references unresolved. `baseDoc` | `String=null`. If provided in the form of `URL`, will be able to resolve circular `JSON-References`. ##### Cache Resolver algorithm caches results of remotely fetched and resolved OpenAPI definitions in an internal cache. When using long-running threads that periodically pulls a OpenAPI definitions, the internal cache may cause a problem. In order to avoid this problem, it is possible to explicitly clear the internal cache before doing resolution. ```js import SwaggerClient from 'swagger-client'; SwaggerClient.clearCache(); SwaggerClient.resolve({ url: 'https://raw.githubusercontent.com/swagger-api/swagger-petstore/main/src/main/resources/openapi.yaml'}).then(swaggerClient => { swaggerClient.spec; swaggerClient.errors; }); ``` > *__Note:__ An internal cache is only involved when doing resolution on remote URLs.*