Skip to content

Commit 0e91bee

Browse files
committed
feat(custom-plugin-decorators): add set-servers-urls example
1 parent 68fcff3 commit 0e91bee

File tree

4 files changed

+171
-0
lines changed

4 files changed

+171
-0
lines changed
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
# Set servers URLs
2+
3+
Authors:
4+
5+
- [`@TKostrzewski`](https://github.com/TKostrzewski), Thomas Kostrzewski
6+
7+
## What this does and why
8+
9+
A custom plugin/decorator pair that sets the API server(s) URL(s) of the OpenAPI specification. If a `servers` field is already present, it will be overwritten.
10+
11+
The `replace-servers-url` [plugin example](https://redocly.com/docs/cli/guides/replace-servers-url) unfortunately does not account for when the `servers` field is not already present in the OpenAPI specification.
12+
13+
Some common use cases for this custom plugin and decorator set include:
14+
15+
- overriding server(s) URL(s) for different deployment environments, all without modifying the original OpenAPI specification.
16+
- ensuring all generated API documentation points to a specific gateway, or proxy endpoint.
17+
- standardizing server(s) URL(s) across multiple OpenAPI specifications, in a monorepo, or microservices architecture.
18+
- injecting mock server(s) URL(s) for testing purposes.
19+
- replacing internal server(s) URL(s) with public-facing server(s) URL(s), before publishing API documentation.
20+
21+
## Code
22+
23+
### Decorator
24+
25+
You can find the full decorator code in the [set-servers-urls-decorator.js](set-servers-urls-decorator.js) file.
26+
27+
The decorator first validates the `serverUrl` argument, and then maps it to the OpenAPI `servers` field.
28+
29+
```javascript
30+
export default function SetServersUrls({ serverUrl = [] }) {
31+
return {
32+
Root: {
33+
leave(node) {
34+
// The serverUrl argument is correct as it is, unfortunately.
35+
// Renaming it to serverUrls breaks the plugin functionality.
36+
const serverUrlsIsAValidArray =
37+
Array.isArray(serverUrl) && serverUrl.length > 0;
38+
39+
if (!serverUrlsIsAValidArray) {
40+
return;
41+
}
42+
43+
node.servers = serverUrl.map((url) => ({ url }));
44+
},
45+
},
46+
};
47+
}
48+
```
49+
50+
### Plugin
51+
52+
You can find the full plugin code in the [set-servers-urls-plugin.js](set-servers-urls-plugin.js) file.
53+
54+
```javascript
55+
const setServersUrlsDecorator = {
56+
oas3: {
57+
"set-servers-urls-decorator": SetServersUrls,
58+
},
59+
};
60+
61+
export default function setServersUrlsPlugin() {
62+
return {
63+
id: "set-servers-urls-plugin",
64+
decorators: setServersUrlsDecorator,
65+
};
66+
}
67+
```
68+
69+
### redocly.yaml
70+
71+
You can find the full configuration in the [redocly.yaml](redocly.yaml) file.
72+
73+
```yaml
74+
apis:
75+
api-one-name:
76+
root: api-one-definition.yaml
77+
decorators:
78+
set-servers-urls-plugin/set-servers-urls-decorator:
79+
serverUrl:
80+
[
81+
"https://api-one.development.com",
82+
"https://api-one.staging.com",
83+
"https://api-one.production.com",
84+
]
85+
plugins:
86+
- "./set-servers-urls-plugin.js"
87+
```
88+
89+
## Examples
90+
91+
With the `redocly.yaml` configuration above, and an example OpenAPI description (saved within a `api-one-definition.yaml` file) as such:
92+
93+
```yaml
94+
openapi: 3.1.0
95+
info:
96+
title: Redocly Museum API
97+
...
98+
servers:
99+
- url: "https://redocly.com/_mock/docs/openapi/museum-api"
100+
paths:
101+
...
102+
```
103+
104+
The resulting OpenAPI description (after applying the decorator) would be:
105+
106+
```yaml
107+
openapi: 3.1.0
108+
info:
109+
title: Redocly Museum API
110+
...
111+
servers:
112+
- url: 'https://api-one.development.com'
113+
- url: 'https://api-one.staging.com'
114+
- url: 'https://api-one.production.com'
115+
paths:
116+
...
117+
```
118+
119+
## References
120+
121+
- Redocly CLI - [Replace servers URL plugin example](https://redocly.com/docs/cli/guides/replace-servers-url)
122+
- OpenAPI specification v3.1.0 - [Servers Object](https://spec.openapis.org/oas/v3.1.0#server-object)
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
apis:
2+
api-one-name:
3+
root: api-one-definition.yaml
4+
decorators:
5+
set-servers-urls-plugin/set-servers-urls-decorator:
6+
serverUrl:
7+
[
8+
"https://api-one.development.com",
9+
"https://api-one.staging.com",
10+
"https://api-one.production.com",
11+
]
12+
plugins:
13+
- "./set-servers-urls-plugin.js"
14+
extends:
15+
- recommended
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/** @type {import('@redocly/cli').OasDecorator} */
2+
export default function SetServersUrls({ serverUrl = [] }) {
3+
return {
4+
Root: {
5+
leave(node) {
6+
// The serverUrl argument is correct as it is, unfortunately.
7+
// Renaming it to serverUrls breaks the plugin functionality.
8+
const serverUrlsIsAValidArray =
9+
Array.isArray(serverUrl) && serverUrl.length > 0;
10+
11+
if (!serverUrlsIsAValidArray) {
12+
return;
13+
}
14+
15+
node.servers = serverUrl.map((url) => ({ url }));
16+
},
17+
},
18+
};
19+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import SetServersUrls from "./set-servers-urls-decorator.js";
2+
3+
/** @type {import('@redocly/cli').DecoratorsConfig} */
4+
const setServersUrlsDecorator = {
5+
oas3: {
6+
"set-servers-urls-decorator": SetServersUrls,
7+
},
8+
};
9+
10+
export default function setServersUrlsPlugin() {
11+
return {
12+
id: "set-servers-urls-plugin",
13+
decorators: setServersUrlsDecorator,
14+
};
15+
}

0 commit comments

Comments
 (0)