@superhero/oas v4.6.10
OAS
A Node.js library for integrating OpenAPI specifications into an application. With @superhero/oas, you can define, validate, and route API operations using OpenAPI's structured standard.
OBS! This is an early release of this component.
Features
- Builds API routes from OpenAPI specifications.
- Validate request parameters, bodies, and responses using OpenAPI schemas.
- Supports OpenAPI components for modular and reusable specifications.
- Middlewares for handling parameters, request bodies, and responses.
Installation
Install via npm:
npm install @superhero/oasUsage
Defining an OpenAPI Specification
For detailed information about how to define an OpenAPI Specification, refer to the OpenAPI Specification Documentation.
Bootstrapping the Library
Set up and bootstrap the @superhero/oas library with your specification:
import HttpServer from '@superhero/http-server';
import Locator from '@superhero/locator';
import OAS from '@superhero/oas';
import Router from '@superhero/router';
// Instantiate the service locator
const locator = new Locator();
// Instantiate the router
const router = new Router(locator);
// Instantiate the server
const server = new HttpServer(router);
// Instantiate the OAS instance
const oas = new OAS(router)
// Register the route dispatcher service
locator.set('hello-dispatcher', {
dispatch: (request, session) => {
session.view.body.message = 'Hello, World!';
},
});
// Bootstrap and start the server
await server.bootstrap();
await server.listen(3000);
// Routes
const specification = {
paths: {
'/example': {
get: {
operationId: 'hello-dispatcher',
responses: { 200: { description: 'Hello World' } },
},
},
},
};
oas.bootstrap(specification)Adding Middleware for Parameters and Request Bodies
The library automatically adds middleware for validating request parameters, request bodies, and responses as defined in the specification.
For example:
const specification = {
paths: {
'/example': {
post: {
operationId: 'example',
requestBody: {
required: true,
content: {
'application/json': {
schema: {
type: 'object',
properties: {
name: { type: 'string', minLength: 1 },
age: { type: 'integer', minimum: 0 },
},
required: ['name'],
},
},
},
},
responses: {
201: { description: 'Created' },
400: { description: 'Validation Error' },
},
},
},
},
};
oas.bootstrap(specification);This will ensure:
- Request parameters are validated.
- Request bodies are checked against the defined schema.
- Responses are validated according to the specification.
- A dispatcher called
examplewill dispatch the request.
Setting Up a Dispatcher
Map the operationId from your specification to a dispatcher:
locate.set('example-reader', {
dispatch: (request, session) => {
session.view.body = { message: `Fetched data for ID: ${request.param.id}` };
},
});
locate.set('example-writer', {
dispatch: (request, session) => {
session.view.body = { message: `Created data for ${request.body.name}` };
},
});Error Handling
The library throws descriptive errors (will be improved on in comming versions) for invalid specifications or operations.
Testing
The test suite uses Node.js's built-in testing module.
Running Tests
To run the tests, execute:
npm testTest Coverage
▶ @superhero/oas/schemas
▶ Supported attributes
▶ type:boolean
✔ nullable enum (3.35678ms)
✔ throws if invalid enum type (0.300923ms)
✔ casts strings that can be interpreted as a boolean value to boolean (0.325861ms)
✔ throws if invalid (0.270627ms)
✔ type:boolean (6.104481ms)
▶ type:integer
✔ nullable enum (0.455196ms)
✔ minimum (0.190364ms)
✔ maximum (0.276653ms)
✔ exclusiveMinimum (0.311391ms)
✔ exclusiveMaximum (0.678551ms)
✔ multipleOf (0.457454ms)
✔ format int32 (0.319436ms)
✔ format int64 (0.357137ms)
✔ throws if invalid format (0.152509ms)
✔ throws if invalid enum type (0.134188ms)
✔ throws if a decimal (0.217675ms)
✔ type:integer (5.643484ms)
▶ type:number
✔ nullable enum (0.549315ms)
✔ format float (0.21403ms)
✔ format double (0.186924ms)
✔ throws if invalid enum type (0.221865ms)
✔ casts strings that can be interpreted as a number value to number (0.107354ms)
✔ type:number (2.023555ms)
▶ type:string
✔ nullable enum (1.457643ms)
✔ minLength (0.20732ms)
✔ maxLength (0.154873ms)
✔ pattern (0.303383ms)
✔ format date (1.632527ms)
✔ format time (0.389043ms)
✔ format datetime (0.413008ms)
✔ format base64 (0.432533ms)
✔ format email (0.23688ms)
✔ format ipv4 (1.006419ms)
✔ format ipv6 (6.590692ms)
✔ url (0.494795ms)
✔ format uuid (0.340933ms)
✔ throws if invalid enum type (0.139166ms)
✔ type:string (15.599415ms)
▶ type:null
✔ throws if not null (0.296927ms)
✔ throws if value is null and type is not null (0.210403ms)
✔ type:null (0.874171ms)
✔ type:undefined (0.140063ms)
▶ type:array
✔ throws if invalid type (0.359969ms)
✔ items (1.020706ms)
✔ additionalItems (0.21037ms)
✔ minItems (0.248753ms)
✔ maxItems (0.329635ms)
✔ uniqueItems (0.890805ms)
✔ enum (0.259908ms)
✔ throws if invalid enum type (0.304887ms)
✔ nullable enum (0.764214ms)
✔ nullable items (0.265034ms)
✔ nullable enum items (0.169632ms)
✔ type:array (6.446302ms)
▶ type:object
✔ throws if invalid type (0.282162ms)
✔ additionalProperties (0.33254ms)
✔ minProperties (0.22744ms)
✔ maxProperties (0.203384ms)
✔ propertyNames pattern (0.313919ms)
✔ nullable (0.111406ms)
✔ enum (0.243711ms)
✔ nullable enum (0.304399ms)
✔ throws if invalid enum type (0.132201ms)
✔ type:object (3.92496ms)
✔ type:invalid throws (0.146378ms)
▶ readOnly
✔ when is reading (0.130151ms)
✔ when is writing (0.166433ms)
✔ readOnly (0.514571ms)
▶ writeOnly
✔ when is reading (0.19847ms)
✔ when is writing (0.111985ms)
✔ writeOnly (0.519254ms)
▶ default
✔ when no value (0.122471ms)
✔ when value (0.109269ms)
✔ default (0.423953ms)
▶ if/then/else
✔ then (0.116916ms)
✔ else (0.202285ms)
✔ throws if invalid (0.391854ms)
✔ if/then/else (1.17015ms)
✔ not (0.250797ms)
▶ allOf
✔ result only what is expected (0.181802ms)
✔ throws if all are not valid (0.168471ms)
✔ allOf (1.106621ms)
▶ anyOf
✔ conforms to valid schema (0.147225ms)
✔ throws if none is valid (0.170714ms)
✔ anyOf (0.547187ms)
▶ oneOf
✔ conforms to valid schema (0.157463ms)
✔ throws if none is valid (0.12812ms)
✔ throws if more than one is valid (0.129512ms)
✔ oneOf (0.726333ms)
✔ const (0.305981ms)
✔ deep const (1.424227ms)
✔ throws on invalid $ref (0.605318ms)
✔ throws on invalid schema (0.147341ms)
✔ Supported attributes (49.751109ms)
✔ @superhero/oas/schemas (50.297111ms)
▶ @superhero/oas
✔ Can set a simple specification (79.360931ms)
✔ Can add middleware for requestBody content (10.793273ms)
✔ Can add middleware for parameters (8.350745ms)
▶ Specification with reference to components
✔ GET method using default parameter (31.754399ms)
✔ GET method not using required parameter (6.148027ms)
✔ GET method using path parameter (5.035696ms)
✔ GET method using query parameter (5.464326ms)
✔ GET method using header parameter (4.530933ms)
✔ POST method using request body (4.042791ms)
✔ Specification with reference to components (72.699754ms)
✔ Throws error for invalid paths type in specification (8.362196ms)
✔ Throws error for missing response (4.73213ms)
✔ Throws error for missing operationId in operation (7.265388ms)
✔ Throws error for missing responses in operation (7.791663ms)
✔ Throws error for missing response code (7.583666ms)
✔ Throws error for unsupported content type in requestBody (7.55338ms)
✔ Throws error for invalid parameters type (5.039937ms)
✔ @superhero/oas (222.477838ms)
tests 110
suites 3
pass 110
-----------------------------------------------------------------------------------------------------
file | line % | branch % | funcs % | uncovered lines
-----------------------------------------------------------------------------------------------------
components | | | |
abstraction.js | 76.10 | 72.00 | 100.00 | 42-48 63-68 71-76 89-93 100-104 111-115 140-143
headers.js | 69.14 | 64.29 | 66.67 | 30-33 37-38 43-46 53-54 63-66 70-75 78-80
parameters.js | 70.43 | 77.78 | 100.00 | 65-69 98-101 128-132 142-164 167-184
request-bodies.js | 78.38 | 65.00 | 100.00 | 50-55 58-61 70-73 90-94 105-109
responses.js | 86.26 | 80.00 | 100.00 | 40-44 67-71 88-91 116-119
schemas.js | 100.00 | 98.00 | 100.00 |
schemas.test.js | 100.00 | 100.00 | 100.00 |
index.js | 93.24 | 86.36 | 100.00 | 112-115 118-123
index.test.js | 100.00 | 100.00 | 96.55 |
middleware | | | |
parameters.js | 90.91 | 88.89 | 100.00 | 39-42
request-bodies.js | 100.00 | 100.00 | 100.00 |
responses.js | 100.00 | 100.00 | 100.00 |
-----------------------------------------------------------------------------------------------------
all files | 94.81 | 94.28 | 99.26 |
-----------------------------------------------------------------------------------------------------License
This project is licensed under the MIT License.
Contributing
Feel free to submit issues or pull requests for improvements or additional features.
9 months ago
10 months ago
9 months ago
9 months ago
10 months ago
10 months ago
11 months ago
11 months ago
10 months ago
10 months ago
11 months ago
11 months ago
10 months ago
10 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
10 months ago
11 months ago
11 months ago
11 months ago
9 months ago
10 months ago
11 months ago
11 months ago
11 months ago
12 months ago
12 months ago
1 year ago
1 year ago