@superhero/http-server-using-oas 4.7.4 → 4.7.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -0
- package/README.md +178 -0
- package/config.json +2 -1
- package/index.test.js +24 -10
- package/package.json +6 -6
package/CHANGELOG.md
ADDED
package/README.md
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
# HTTP Server using OAS
|
|
2
|
+
|
|
3
|
+
A routing bridge module that connects OpenAPI Specification (OAS) definitions with the `@superhero/http-server`, enabling automatic route creation, request validation, and response conformance. Designed for the Superhero Tool-Chain, this module allows for fully declarative HTTP APIs, grounded in specification adapted architecture.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Specification driven routing**: Dynamically registers routes from OpenAPI JSON specifications.
|
|
8
|
+
- **Schema validation**: Automatically validates parameters, request bodies, and responses.
|
|
9
|
+
- **Component reference resolution**: Supports `$ref` linking across parameters, request bodies, responses, and schemas.
|
|
10
|
+
- **Dynamic middleware injection**: Adds validation middleware as required by the specifications.
|
|
11
|
+
- **Declarative dispatcher mapping**: Connects OAS operations directly to logic handlers.
|
|
12
|
+
- **Robust error handling**: Emits structured errors for invalid config or unsupported content types.
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install @superhero/http-server-using-oas
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Usage
|
|
21
|
+
|
|
22
|
+
You must supply an **OpenAPI 3.x Specification as a JSON object** in the `oas` configuration field.
|
|
23
|
+
|
|
24
|
+
```javascript
|
|
25
|
+
import Core from '@superhero/core'
|
|
26
|
+
|
|
27
|
+
const core = new Core()
|
|
28
|
+
|
|
29
|
+
await core.add('@superhero/oas')
|
|
30
|
+
await core.add('@superhero/http-server')
|
|
31
|
+
await core.add('@superhero/http-server-using-oas')
|
|
32
|
+
|
|
33
|
+
core.locate.config.assign({
|
|
34
|
+
oas: {
|
|
35
|
+
paths: {
|
|
36
|
+
"/foo": {
|
|
37
|
+
"get": { "responses": { "200": {} }},
|
|
38
|
+
"post": { "responses": { "200": {} }}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
await core.bootstrap()
|
|
45
|
+
|
|
46
|
+
const oasBridge = core.locate('@superhero/http-server-using-oas')
|
|
47
|
+
|
|
48
|
+
oasBridge.setOasRoute('/foo', 'get', 'dispatcher/for/get')
|
|
49
|
+
oasBridge.setOasRoute('/foo', 'post', 'dispatcher/for/post')
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Automatic Middleware Injection
|
|
53
|
+
|
|
54
|
+
Depending on the OAS operation, the following are automatically injected:
|
|
55
|
+
|
|
56
|
+
- `@superhero/http-server-using-oas/dispatcher/upstream/parameters`
|
|
57
|
+
- `@superhero/http-server-using-oas/dispatcher/upstream/request-bodies`
|
|
58
|
+
- `@superhero/http-server-using-oas/dispatcher/downstream/responses`
|
|
59
|
+
|
|
60
|
+
Supported `requestBody.content-type`:
|
|
61
|
+
- Only `application/json` is currently supported
|
|
62
|
+
|
|
63
|
+
## More Complete OAS Example
|
|
64
|
+
|
|
65
|
+
This module resolves `$ref`-based components in OpenAPI JSON specifications:
|
|
66
|
+
|
|
67
|
+
```json
|
|
68
|
+
{
|
|
69
|
+
"paths": {
|
|
70
|
+
"/example": {
|
|
71
|
+
"post": {
|
|
72
|
+
"requestBody": {
|
|
73
|
+
"$ref": "#/components/requestBodies/ExampleRequestBody"
|
|
74
|
+
},
|
|
75
|
+
"responses": {
|
|
76
|
+
"200": {
|
|
77
|
+
"$ref": "#/components/responses/SuccessResult"
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
"components": {
|
|
84
|
+
"requestBodies": {
|
|
85
|
+
"ExampleRequestBody": {
|
|
86
|
+
"content": {
|
|
87
|
+
"application/json": {
|
|
88
|
+
"schema": {
|
|
89
|
+
"$ref": "#/components/schemas/Foo"
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
"responses": {
|
|
96
|
+
"SuccessResult": {
|
|
97
|
+
"description": "Successful result",
|
|
98
|
+
"content": {
|
|
99
|
+
"application/json": {
|
|
100
|
+
"schema": {
|
|
101
|
+
"$ref": "#/components/schemas/Result"
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
"schemas": {
|
|
108
|
+
"Foo": {
|
|
109
|
+
"type": "object",
|
|
110
|
+
"properties": {
|
|
111
|
+
"foo": { "type": "string" }
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
"Result": {
|
|
115
|
+
"type": "object",
|
|
116
|
+
"properties": {
|
|
117
|
+
"result": { "type": "string" }
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Configuration Summary
|
|
126
|
+
|
|
127
|
+
| Method/Property | Description |
|
|
128
|
+
|--------------------------------------------------------|-----------------------------------------------------------------------|
|
|
129
|
+
| `setOasRoute(path, method, dispatcher, [middlewares])` | Registers a route from the OpenAPI JSON spec |
|
|
130
|
+
| `requestBodyContentTypeRouteMap(type)` | Maps supported content-types to upstream middleware |
|
|
131
|
+
| Middleware auto-injection | Based on the `parameters`, `requestBody`, and `responses` in the spec |
|
|
132
|
+
| Error signaling | Emits detailed errors on spec validation or misuse |
|
|
133
|
+
|
|
134
|
+
## Tests
|
|
135
|
+
|
|
136
|
+
Run the test suite:
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
npm test
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### Test Coverage
|
|
143
|
+
|
|
144
|
+
```
|
|
145
|
+
────────────────────────────────── ⋅⋆ Suite ⋆⋅ ─────────────────────────────────
|
|
146
|
+
|
|
147
|
+
@superhero/http-server-using-oas
|
|
148
|
+
├─ Can set a simple specification ✔ 107.543ms
|
|
149
|
+
├─ Can add middleware for requestBody content ✔ 16.743ms
|
|
150
|
+
├─ Can add middleware for parameters ✔ 19.857ms
|
|
151
|
+
├─ Specification with reference to components
|
|
152
|
+
│ ├─ GET method using default parameter query parameter ✔ 37.413ms
|
|
153
|
+
│ ├─ GET method not using required parameter ✔ 9.606ms
|
|
154
|
+
│ ├─ GET method using bar parameter ✔ 5.497ms
|
|
155
|
+
│ ├─ GET method using header parameter ✔ 4.792ms
|
|
156
|
+
│ ├─ POST method using request body ✔ 11.069ms
|
|
157
|
+
│ └─ ✔ 91.067ms
|
|
158
|
+
└─ ✔ 238.450ms
|
|
159
|
+
|
|
160
|
+
─────────────────────────────────── Coverage ───────────────────────────────────
|
|
161
|
+
|
|
162
|
+
Files Coverage Functions Branches
|
|
163
|
+
dispatcher/downstream/responses.js 69% 75% 80%
|
|
164
|
+
dispatcher/options.js 10% 33% 100%
|
|
165
|
+
dispatcher/upstream/parameters.js 100% 100% 100%
|
|
166
|
+
dispatcher/upstream/request-bodies.js 75% 75% 100%
|
|
167
|
+
index.js 82% 100% 58%
|
|
168
|
+
index.test.js 100% 100% 100%
|
|
169
|
+
Total 68% 88% 83%
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
## License
|
|
173
|
+
|
|
174
|
+
MIT
|
|
175
|
+
|
|
176
|
+
## Contributing
|
|
177
|
+
|
|
178
|
+
Issues and pull requests are welcome.
|
package/config.json
CHANGED
package/index.test.js
CHANGED
|
@@ -111,7 +111,8 @@ suite('@superhero/http-server-using-oas', () =>
|
|
|
111
111
|
{ headers:
|
|
112
112
|
{ ContentType:
|
|
113
113
|
{ required: true,
|
|
114
|
-
schema: { type: 'string' }
|
|
114
|
+
schema: { type: 'string' }
|
|
115
|
+
}
|
|
115
116
|
},
|
|
116
117
|
parameters:
|
|
117
118
|
{ DefaultFoo: { name: 'foo', in: 'query', required: true, schema: { '$ref': '#/components/schemas/String' }, nullable: true, default: null },
|
|
@@ -124,7 +125,8 @@ suite('@superhero/http-server-using-oas', () =>
|
|
|
124
125
|
{ ExampleRequestBody: { '$ref': '#/components/requestBodies/GenericRequestBody' },
|
|
125
126
|
GenericRequestBody:
|
|
126
127
|
{ required: true,
|
|
127
|
-
content: { 'application/json': { schema: { '$ref': '#/components/schemas/Foo' }}}
|
|
128
|
+
content: { 'application/json': { schema: { '$ref': '#/components/schemas/Foo' }}}
|
|
129
|
+
}
|
|
128
130
|
},
|
|
129
131
|
responses:
|
|
130
132
|
{ SuccessResult:
|
|
@@ -134,16 +136,19 @@ suite('@superhero/http-server-using-oas', () =>
|
|
|
134
136
|
},
|
|
135
137
|
BadRequest:
|
|
136
138
|
{ description: 'Bad Request',
|
|
137
|
-
schema: { '$ref': '#/components/schemas/Result' }}
|
|
139
|
+
content: { 'application/json': { schema: { '$ref': '#/components/schemas/Result' }}}
|
|
140
|
+
}
|
|
138
141
|
},
|
|
139
142
|
schemas:
|
|
140
143
|
{ String: { type: 'string' },
|
|
141
144
|
Foo:
|
|
142
145
|
{ type: 'object',
|
|
143
|
-
properties: { foo: { '$ref': '#/components/schemas/String' }}
|
|
146
|
+
properties: { foo: { '$ref': '#/components/schemas/String' }}
|
|
147
|
+
},
|
|
144
148
|
Result:
|
|
145
149
|
{ type: 'object',
|
|
146
|
-
properties: { result: { '$ref': '#/components/schemas/String' } }
|
|
150
|
+
properties: { result: { '$ref': '#/components/schemas/String' } }
|
|
151
|
+
}
|
|
147
152
|
}
|
|
148
153
|
},
|
|
149
154
|
paths:
|
|
@@ -152,21 +157,27 @@ suite('@superhero/http-server-using-oas', () =>
|
|
|
152
157
|
{ parameters: [{ '$ref': '#/components/parameters/DefaultFoo' }],
|
|
153
158
|
responses:
|
|
154
159
|
{ 200: { '$ref': '#/components/responses/SuccessResult' },
|
|
155
|
-
400: { '$ref': '#/components/responses/BadRequest' }
|
|
160
|
+
400: { '$ref': '#/components/responses/BadRequest' }
|
|
161
|
+
}
|
|
162
|
+
}
|
|
156
163
|
},
|
|
157
164
|
'/example/required':
|
|
158
165
|
{ get:
|
|
159
166
|
{ parameters: [{ '$ref': '#/components/parameters/RequiredFoo' }],
|
|
160
167
|
responses:
|
|
161
168
|
{ 200: { '$ref': '#/components/responses/SuccessResult' },
|
|
162
|
-
400: { '$ref': '#/components/responses/BadRequest' }
|
|
169
|
+
400: { '$ref': '#/components/responses/BadRequest' }
|
|
170
|
+
}
|
|
171
|
+
}
|
|
163
172
|
},
|
|
164
173
|
'/example/foo/{foo}':
|
|
165
174
|
{ get:
|
|
166
175
|
{ parameters: [{ '$ref': '#/components/parameters/PathFoo' }],
|
|
167
176
|
responses:
|
|
168
177
|
{ 200: { '$ref': '#/components/responses/SuccessResult' },
|
|
169
|
-
400: { '$ref': '#/components/responses/BadRequest' }
|
|
178
|
+
400: { '$ref': '#/components/responses/BadRequest' }
|
|
179
|
+
}
|
|
180
|
+
}
|
|
170
181
|
},
|
|
171
182
|
'/example':
|
|
172
183
|
{ get:
|
|
@@ -176,13 +187,16 @@ suite('@superhero/http-server-using-oas', () =>
|
|
|
176
187
|
],
|
|
177
188
|
responses:
|
|
178
189
|
{ 200: { '$ref': '#/components/responses/SuccessResult' },
|
|
179
|
-
400: { '$ref': '#/components/responses/BadRequest' }
|
|
190
|
+
400: { '$ref': '#/components/responses/BadRequest' }
|
|
191
|
+
}
|
|
180
192
|
},
|
|
181
193
|
post:
|
|
182
194
|
{ requestBody: { '$ref': '#/components/requestBodies/ExampleRequestBody' },
|
|
183
195
|
responses:
|
|
184
196
|
{ 200: { '$ref': '#/components/responses/SuccessResult' },
|
|
185
|
-
400: { '$ref': '#/components/responses/BadRequest' }}}}
|
|
197
|
+
400: { '$ref': '#/components/responses/BadRequest' }}}}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
186
200
|
|
|
187
201
|
core.locate.config.assign({ oas:specification })
|
|
188
202
|
await core.bootstrap()
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@superhero/http-server-using-oas",
|
|
3
|
-
"version": "4.7.
|
|
3
|
+
"version": "4.7.6",
|
|
4
4
|
"description": "Integrates the HTTP server and OAS (OpenAPI Specification) @superhero components",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"HTTP 2.0",
|
|
@@ -23,14 +23,14 @@
|
|
|
23
23
|
"test": "syntax-check; node --test --test-reporter=@superhero/audit/reporter --experimental-test-coverage"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@superhero/oas": "4.7.
|
|
27
|
-
"@superhero/http-server": "4.7.
|
|
26
|
+
"@superhero/oas": "4.7.6",
|
|
27
|
+
"@superhero/http-server": "4.7.6"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
|
-
"@superhero/audit": "4.7.
|
|
30
|
+
"@superhero/audit": "4.7.6",
|
|
31
31
|
"@superhero/syntax-check": "0.0.2",
|
|
32
|
-
"@superhero/http-request": "4.7.
|
|
33
|
-
"@superhero/core": "4.7.
|
|
32
|
+
"@superhero/http-request": "4.7.6",
|
|
33
|
+
"@superhero/core": "4.7.6"
|
|
34
34
|
},
|
|
35
35
|
"author": {
|
|
36
36
|
"name": "Erik Landvall",
|