kogosoftwarellc / open-api Goto Github PK
View Code? Open in Web Editor NEWA Monorepo of various packages to power OpenAPI in node
License: MIT License
A Monorepo of various packages to power OpenAPI in node
License: MIT License
Any plans in the works to support 3.0.0?
https://github.com/OAI/OpenAPI-Specification/blob/OpenAPI.next/README.md
Looks like it's expected to be released in July.
Hello,
I have an endpoint documented like this:
post.apiDoc = {
description: 'Upload an image for the category',
operationId: 'uploadCategoryImage',
tags: ['categories'],
consumes: ['multipart/form-data'],
parameters: [
{
name: 'image',
in: 'formData',
type: 'file',
description: 'An image for this category',
required: true
}
],
responses: {
201: {
description: 'Image successfully uploaded'
},
default: {
description: 'Unexpected error',
schema: {
$ref: '#/definitions/Error'
}
}
}
};
In the Swagger UI, a file upload thing is visible:
However, I keep getting this error when I send a file:
{
path: 'image',
errorCode: 'required.openapi.validation',
message: 'instance requires property "image"',
location: 'body'
}
I do have a Content-Type: multipart/form-data
header in the HTTP request.
Am I doing something wrong or is it a bug?
If I'm not mistaken, express-openapi
is using express-openapi-validation
by default and will validate requests to endpoints when the endpoint has given a value to the apiDoc
parameter.
The validation is working correctly, but the response that a user receives is not helpful. Below is an example of what I get when hitting an endpoint with an improper request using Postman:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Error</title>
</head>
<body>
<pre>[object Object]</pre>
</body>
</html>
Providing a custom errorTransformer
function when initializing express-openapi
doesn't solve the issue.
I've done some debugging and tracing and believe this issue is being caused by the way express-openapi-validation
formats the error object it passes into next()
. In short, the error object does not have a stack
property and so toString()
is called on the object before sending it out, resulting in the [object Object]
we see in the response.
Maybe I'm missing some fundamental solution here, but it would be much nicer to have the response sent back as JSON, or at the very least a message that simply says "Incorrect data format received."
I can go into further detail and provide example code another time if you'd like.
Hi,
Thanks for express-openapi. I really appreciate to use it :)
But I have a problem, I need to expose fields which the type strings that could be nullable.
This following code works when i run the server based on express-api :
responses: { 200: { schema: { title: 'MyObject', properties: { myfield: { type: ['string', 'null'],
But it's not valid against Swagger (editor.swagger.io) :(
Semantic error at definitions.MyObject.myfield "type" should be a string
Do you have a valid way to use nullable fields with express-openapi ?
Thanks by advance !
And Thanks for this top library.
Regards,
F.
I use the dist folder files in master, and use $ref to reference external yaml file, but it can't resolved.
my yaml format is :
parameters:
-
name: request
in: body
required: true
schema:
$ref: './deviceManageDF.yaml#/definitions/AddDeviceDTONA2Cloud'
even modified with full acess path as:
parameters:
-
name: request
in: body
required: true
schema:
$ref: 'http://localhost:8080/swagger-ui/deviceManageDF.yaml#/definitions/AddDeviceDTONA2Cloud'
It displayed:
http://localhost:8080/swagger-ui/deviceManageDF.yaml#/definitions/AddDeviceDTOCloud2NA is not defined!
delete is a javascript keyword / unary operator. It is invalid for functions to be named delete in javascript, so it would be good to support a del alias to allow for this:
module.exports = {
del
};
function del(req, res, next) {
// ...
}
Now my api receives json schema object.
so, i wrote:
// in handler
post.apiDoc = {
description: "create new schema definition",
operationId: "createSchema",
parameters: [
{
in: 'body',
name: 'schema',
schema: {$ref: '#/definitions/schema' }
}
],
responses: {
"201": { $ref: '#/responses/created' },
"default": { $ref: "#/responses/error" }
}
}
// in apidoc.js#definitions
{
"schema": { "$ref": "http://json-schema.org/schema" }
}
Then i sent request to it and got:
{
"status":400,
"errors":[
{
"message":"no such schema <http://json-schema.org/schema>",
"schema":{"$ref":"http://json-schema.org/schema"},
"location":"body"
}
]
}
This will allow security to be applied to all operations by path based on regex
I.E.
applySecurity: [
[/^\/something/, [{mySecurity: []}]]
]
Given the following operation definition
{
post: {
summary: 'Application information',
operationId: 'info',
tags: ['/info'],
parameters: [
{
name: 'booleanParam',
in: 'formData',
required: true,
type: 'boolean',
default: false
}
],
responses: {
200: {
description: 'Success',
schema: {
$ref: '#/definitions/Success'
}
},
default: {
description: 'Error',
schema: {
$ref: '#/definitions/Error'
}
}
}
}
}
and then calling using the following
curl -X POST --header 'Content-Type: application/x-www-form-urlencoded' --header 'Accept: text/html' -d 'booleanParam=false' 'http://localhost:3200/api/info'
the following error is returned
error: status=400, errors=[path=booleanParam, errorCode=type.openapi.validation, message=instance.booleanParam is not of a type(s) boolean, location=body]
This came out of #32
Other middleware initialization in if block begins in L.130.
if (methodDoc &&
allowsMiddleware(apiDoc, pathModule, pathItem, methodDoc)) {// add middleware
Security middleware is initialized out of the block.
running the test/sample-projects/with-external-schema-references app and viewing the generated api doc in swagger UI results in html markup displayed as well as errors implying that the external schemas could not be referenced.
Does express-openapi actually attempt to pull the schemas from the uris specified as the keys to the externalSchemas option object? Seems like the with-external-schema-references project inlines the definitions of the schema, and the uri is really just a key.
Liking this more and more so thanks for making such a stellar implementation. Question:
I'm not getting req validation messaging back - ( just 400s ) - can I enable that somehow?
As far as i can see, the execution of any middleware like parameter validation happens based on the apiDoc
property of a single http endpoint / route.
module.exports.GET = () => {} // handler
module.exports.GET.apiDoc = {} // open api route schema
It would be nice if express-openapi could fallback to path-definitions passed to the initialize({ apiDoc })
routine.
That way the developer could choose between having the route-handler and the api-spec in one file or separated.
I'd like to run the following setup:
api.js // openapi.initialize({ apiDoc: loadOpenApiSpec({ path: './' }), paths: './'})
api-doc.yml // swagger: 2.0 ...
paths/some-route/resource.js // module.export.GET = (req, res) => { ... }
paths/some-route/resource.yml // paths: { /some-route/resource: { get: { ... } } }
I would like to load and assemble the whole open-api spec with all path definitions just before passing it to initialize
.
const { sync: globSync } = require('glob');
const deepAssign = require('deep-assign');
const fs = require('fs');
const yaml = require('js-yaml');
module.exports = function loadOpenApiSpec({ version, path, specGlob = '/**/*.yml' }) {
const files = globSync(specGlob, {root: path});
const spec = {};
files.forEach((file) => {
deepAssign(spec, yaml.safeLoad(fs.readFileSync(file, 'utf8')));
});
spec.info.version = version;
return spec;
};
So my idea is to keep backwards compatibility and to allow for populating the "global" spec down to a specific route.
@jsdevel I could submit a PR if you like the idea.
I can't find an option to validate all responses, it gets repetitive to keep doing.
const validationError = res.validateResponse(200, json);
if (validationError) {
return next(validationError);
}
res.json(json);
To be honest I don't like the way which you choose for routing.
What about to make your router optional?
How can it be? For example:
openapi.initialize({
apiDoc: require('./api-doc.js'),
app: app,
router: myRouter // if not set, by default it can be 'fs-routes'
});
If you don't mind, I can try to make PR
I'm trying to get validator to work on the body of this route:
'/filtered':
put:
summary: blah
parameters:
- in: body
name: body
required: true
schema:
type: object
required:
- filtered
properties:
filtered:
description: status of ssid
type: boolean
here are my request parameters:
{ uri: 'http://127.0.0.1/apiv2/filtered', headers: { 'x-api-key': 'blah' }, json: { test: 'test' } }
I expect openapi-express to return 400, because body should be an object with filtered prop. Yet I get 200 response. Swaggerize express worked fine with this one. Am I doing something wrong here? I'll edit this to make it more reproducible after lunch....
I'm eager to switch over to express-openapi but we're missing one feature which we require: security filtering of the documentation itself. Essentially we only want to show scopes, paths and operations that the user has access to in the documentation. It is described in the spec: https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#security-filtering
Any plans to implement this? It should reuse the security handlers. With swaggerize-express we handle it by adding an explicit route for the documentation which calls a middleware that does the filtering.
app.get('/v1/api-docs', filter_openapi);
Works great!
We've done a similar POC middleware for express-openapi, but the route is overriden, so the filtered api-docs isn't returned. Code for reference below. It would be great if an option to turn on security filtering could be added.
function filter_openapi(req, res, next) {
// remove scopes the user does not have access to
Object.values(api_docs.securityDefinitions).forEach(function (securityDefinition) {
Object.keys(securityDefinition.scopes).forEach(function (scope) {
if (req.user.scope.indexOf(scope) == -1) {
delete securityDefinition.scopes[scope]
}
})
})
// remove paths the user does not have access to
Object.keys(api_docs.paths).forEach(function (path) {
var def = api_docs.paths[path]
verbs.forEach(function (verb) {
var operation = def[verb]
if (!operation) {
return;
}
if (operation.security || api_docs.security) {
var securityDeclarations
if (!operation.security) {
securityDeclarations = api_docs.security
}
else {
securityDeclarations = operation.security
}
securityDeclarations.forEach(function (security) {
const authorizer = require('./authorizers')[Object.keys(security)[0]] // TODO: Fix this fuglymess
authorizer(req, Object.values(security)[0] ,security, function (error, authorized) {
console.log(authorized)
if (!authorized) {
delete def[verb]
}
})
})
}
})
//Check if any operations remain, if not we should remove the paths object also
var operationExists = false
verbs.forEach(function (verb) {
var operation = def[verb]
if (operation) {
operationExists = true
}
})
if (!operationExists) {
delete api_docs.paths[path]
}
})
//Check if definitions are still referenced
if (api_docs.definitions) {
Object.keys(api_docs.definitions).forEach(function (definition) {
var def = '#/definitions/' + definition
if (!_isContains(api_docs, def)) {
delete api_docs.definitions[definition]
}
})
}
//Check if parameters are still referenced
if (api_docs.parameters) {
Object.keys(api_docs.parameters).forEach(function (parameter) {
var def = '#/parameters/' + parameter
if (!_isContains(api_docs, def)) {
delete api_docs.parameters[parameter]
}
})
}
//Check if responses are still referenced
if (api_docs.responses) {
Object.keys(api_docs.responses).forEach(function (response) {
var def = '#/responses/' + response
if (!_isContains(api_docs, def)) {
delete api_docs.responses[response]
}
})
}
// remove empty objects
api_docs = removeEmptyObject(api_docs);
// add back the paths object if it was removed, must be there per the spec
if (!api_docs.paths) {
api_docs.paths = {}
}
next();
}
Just want to say thank you so much for investing time and sharing this package with the community.
It's extremely useful, especially for API first design & development.
Cheers!
Introspecting function parameter names is nasty business. Relying on something like fn.toString()
as a core technique is error prone and hacky. With native object destructuring there is no need.
Hacky parameter name introspection:
function route (fooService) {
fooService.getFoo();
};
const deps = { fooService: {} };
route.apply(route, someInsaneToStringMagic(route, deps));
Clean object destructuring:
module.exports = function route ({ fooService }) {
fooService.getFoo();
};
const deps = { fooService: {} };
route(deps);
I have some code which is fetching an object from an external source and the object matches something I already defined in my apiDoc definitions.
Instead of redefining it with jsonschema, is there a way to run it through the existing validator?
Getting:
September 16 22:59:13: express-openapi: validation errors [
{
"property": "instance.paths./provider.post.parameters[2]",
"message": "is not exactly one from <#/definitions/parameter>,<#/definitions/jsonReference>",
"schema": {
"oneOf": [
{
"$ref": "#/definitions/parameter"
},
{
"$ref": "#/definitions/jsonReference"
}
]
},
"instance": {
"name": "columns",
"in": "body",
"description": "Columns to include in response",
"type": "array",
"schema": {
"$ref": "#/definitions/columnList"
}
},
"name": "oneOf",
"argument": [
"<#/definitions/parameter>",
"<#/definitions/jsonReference>"
],
"stack": "instance.paths./provider.post.parameters[2] is not exactly one from <#/definitions/parameter>,<#/definitions/jsonReference>"
},
{
"property": "instance.paths./provider.post.responses[200]",
"message": "is not exactly one from <#/definitions/response>,<#/definitions/jsonReference>",
"schema": {
"oneOf": [
{
"$ref": "#/definitions/response"
},
{
"$ref": "#/definitions/jsonReference"
}
]
},
"instance": {},
"name": "oneOf",
"argument": [
"<#/definitions/response>",
"<#/definitions/jsonReference>"
],
"stack": "instance.paths./provider.post.responses[200] is not exactly one from <#/definitions/response>,<#/definitions/jsonReference>"
}
]
when I try to do the example in the readme
I'm a bit new to openapi but it seems like it's not recognizing 200
as a valid responses key, which I believe it should be
... michael
This may already be included somewhere, but it would be awesome if there was an option to strip out parameters that aren't in the docs. For example:
If a query parameter age
is defined, but ?age=30&foo=bar
is passed, I would like req.query
to only contain age
.
I'm not sure which underlying express-openapi-*
module would contain this, or perhaps it would be a new one.
All the examples in the test suite have API definitions similar to
responses: { default: { $ref: '#/definitions/Error' } }
These are flagged as errors in the Swagger Editor.
A valid alternative is to use
responses: { default: { description: "Unexpected error", schema: { $ref: '#/definitions/Error' } } }
I notice that all logging is hard-coded to use Console. Is there some way to redirect this modules console output to a application specific logger so it can be routed to eg, a file then ELK, like all the other logs in our api?
When express-openapi is mounted on a sub app, the basePath ignores the mount path of the parent app.
var app = express(),
sub = express(),
sub2 = express();
openapi.initialize({
apiDoc: require('./api-doc.js'),
app: sub2,
routes: './api-routes'
});
sub.use('/subapp2', sub2);
app.use('/subapp', sub);
If ./api-doc.js
has a basePath of /v1
, I would expect the basePath in the generated api doc in this case to be /subapp/subapp2/v1
. Instead, the basePath of the api doc is /subapp2/v1
, ignoring the highest mount path.
I'm thinking the project could benefit from using lerna. That way the middleware etc. could be brought into the same repo. Doing so could make maintenance easier as PRs, issues and so forth wouldn't be spread across multiple repositories. Looking for thoughts from the community.
packages/express-openapi
with the exception of files that belong in the project root i.e. .travis.yml
etc.packages/
First off thanks for the framework. It's been very useful for growing my knowledge of OpenAPI and the ecosystem while getting prototypes up fast!
I was wondering if there was a best practice for utilizing and working off of route parameters. All examples end in a {id}.js file, but what if I want to have a nested structure against {id}?
For example, two routes such as:
/items/{id}/this
/items/{id}/that
There are two primary issues I'm running into and wondering what you think best practice would be:
loadItem
helper that runs before either route? As far as I can tell, any utility functions can't go under the routes directory, as it would be processed as a route.Both of these may also be alleviated by the routing refactor in #12 , but not sure the timeline on that.
This issue is to request feedback from the community so express-openapi
may be improved. For any who wish not to be apart of this, please comment herein with please remove me
and I'll delete any comment herein containing your @ mention.
The only thing I don't like about express-openapi is the "convention based programming", I found very confusing and limiting.
I would prefer a simple javascript api doc with embedded handlers.
openapi.initialize({
app: app,
swagger: '2.0',
basePath: '/v1',
info: {
title: 'App',
version: '1.0.0',
},
paths: {
'/users': {
get: {
parameters: [],
responses: {
200: {
description: 'Get all users',
schema: {
type: 'array',
items: {
title: 'User',
type: 'object',
properties: {
name: {
type: 'string'
}
}
},
}
}
},
handler(req, res) {
res.json([{name: 'Dale'}]);
}
},
post: {
handler(req, res) {
res.status(201);
}
}
},
'/users/{userId}': {
get: {
handler(req, res) {
res.json({name: 'Dale'});
}
}
}
}
});
You can use modules to split up the code, you have the full javascript language to generate routes or do whatever you like.
openapi.initialize({
app: app,
swagger: '2.0',
basePath: '/v1',
info: {
title: 'App',
version: '1.0.0',
},
paths: {
'/users': require('./routes/users'),
'/messages': {
'get': require('./routes/messages').get
},
'/books': createCrudEndpoints("Books"),
...require('./lotsOfEndpointsUsingSpread')
}
});
The existing convention based system could be used to build this structure internally.
Hi I'm noob,
The paths I want look something like this:
/v1/resource/{type}/
/v1/resource/{type}/something
I assume I'll need this directory structure :
|-<package>
|-v1
|-resource
|-{type}
|-index.js
|-something.js
however it doesn't seem to be working. It is returning 404 for either endpoint.
The documentation only helps with a specific type of nested pattern and doesn't have any further examples for this particular pattern I'm having trouble with.
I have tried various other directory structures including...
|-resource
|-{type}.js
|-{type}
|-something
but that didn't help either
npm install express-openapi fails because it cannot create the file name ":id.js" from the sample-projects.
npm install express-openapi --save
npm ERR! tar.unpack untar error C:\Users\fries\AppData\Roaming\npm-cache\express-openapi\0.4.2\package.tgz
npm WARN EPACKAGEJSON [email protected] No repository field.
npm ERR! Windows_NT 10.0.10586
npm ERR! argv "C:\Program Files\nodejs\node.exe" "C:\Program Files\nodejs\node_modules\npm\bin\npm-cli.js" "install" "express-openapi" "--save"
npm ERR! node v5.4.1
npm ERR! npm v3.3.12
npm ERR! path C:\projects\misc-swagger-howto\nodejs\node_modules.staging\express-openapi-2cbd6e854429c6f69613c40e36d233e3\test\sample-projects\basic-usage\api-routes\users:id.js
npm ERR! code ENOENT
npm ERR! errno -4058
npm ERR! syscall open
npm ERR! enoent ENOENT: no such file or directory, open 'C:\projects\misc-swagger-howto\nodejs\node_modules.staging\express-openapi-2cbd6e854429c6f69613c40e36d233e3\test\sample-projects\basic-usage\api-routes\users:id.js'
npm ERR! enoent This is most likely not a problem with npm itself
npm ERR! enoent and is related to npm not being able to find a file.
npm ERR! enoent
npm ERR! Please include the following file with any support request:
npm ERR! C:\projects\misc-swagger-howto\nodejs\npm-debug.log
Per my convo with @jsdevel on Gitter, I'd like to propose adding some implementation for decorators.
ZooController.ts
@controller({
// default route
route: '/zoo'
// add additional middlewares for express
middlewares: [ ... ],
// custom override for global spec
spec: './zoo-spec.yml'
})
export class ZooController {
@api(‘/get’, [ ...middlewares ])
getAnimals(req, res, next) {
// doo stuff
}
}
App.ts
import { ZooController } from './ZooController';
import { register } from 'express-openapi';
let app = express();
register(app, {
spec: './spec.yml',
route: '/api',
paths: [ '**/*.ts' ]
});
This is kinda angular2-esque with the loaded decorator design pattern which works nicely IMO, define the config at top and the real work happens in body.
If it were me, I'd consider making this project more generic like node-openapi
and then writing this proposal seperate like node-openapi-router
and then add adapters for connect/koa/etc like node-openapi-connect-middleware
.
Hello, thank you for the excellent framework. I have a question about using it to construct modular express applications, where multiple routes are defined in individual npm modules, and the final product is composed from these. Can I call openapi.initialize() multiple times in a single app, once for each module? This implies that instead of a single routes folder, I may have several...
When the api docs json is requested the basePath is automatically updated to include the baseUrl of the request. It would make sense if the host is also updated to reflect the host in the request object.
This would allow the same code to run in different environments (dev, production, etc) without having to manually change the host.
My application doesn't have anything like '/v1', for a basePath. I need either '' or '/'.
Unfortunately neither option is completely problem free while using express-openapi:
If I set it to '/', I get routing problems, my routes are defined like:
openapi.initialize({
app,
...
paths: [
{
path: '/auth/token',
module: require('./auth_token')
},
...
]
});
If I have a leading '/' in the path for my module, then the route ends up being set up as '//auth/token', which obviously breaks things. If I don't have the leading '/' in the path, I get this error: Error: express-openapi: args.apiDoc was invalid after populating paths.
Alternatively, if I set basePath to '' (or don't set it, as express-openapi defaults it to '') then I can get routing to work, however SwaggerUI will report a problem with the basePath being invalid (supposed to match '^/'),
I've resolved the problem as far as running my application by setting basePath to '' while letting express-openapi set up, and then intercepting the api docs for SwaggerUI with the following hack:
app.use('/api-doc.json', (req, res, next) => {
const json = res.json;
res.json = function(obj) {
obj.basePath = '/';
json.apply(res, arguments);
};
next();
});
Are you planning on supporting OpenAPI 3 at some point?
I tried to add an router-level middleware to expose some routes depending on NODE_ENV
. But I could not figure out how to do it.
I used x-express-openapi-additional-middleware
to include my middleware, but express-openapi does not execute it. There is an elegant way to expose/hide routes depending on NODE_ENV
?
And there is a way to add middleware using api-doc
as json file?
I know this is kind of against the open api documentation, but we are moving legacy public endpoints from .net (query params are case insensitive), and right now we have to disable input validation using "x-express-openapi-disable-validation-middleware", and then we read the parameters by below function:
export function getCaseInsensitiveProperty(query: any, property: string): any {
for (let p in query) {
if (query.hasOwnProperty(p) && property.toLowerCase() === p.toLowerCase()) {
return query[p];
}
}
return null;
}
Meaning we can't benefit from validation rules we already wrote in the open api spec.
Any thoughts on this one?
BTW Great work.
This project has been really nicely designed to be modular with separated middleware, but all of the middleware seems to be included by default. In express, koa and other frameworks all middleware is optional so you are free to add what you wish and use alternatives which allows for a rich ecosystem.
I suggest we define a middleware spec for express-openapi.
function myCoolMiddleware(apiDoc) {
return function (req, res, next) {
// Do stuff
next();
}
}
// or
function myCoolMiddleware(req, res, next) {
const apiDoc = req.apiDoc;
// Do stuff
next();
}
const openapiInstance = openapi.initialize({
});
openapiInstance.use(myCoolMiddleware);
// or
openapi.initialize({
middleware: [myCoolMiddleware, express-openapi-defaults]
});
The following file structure results in the routes being loaded in the wrong order. Note the use of the {id} pattern as windows does not support ":" in file names.
routes/
`home.js
|
`users/
`{id}.js
`query.js
This results in route /users/{id} being defined before /users/query which is not the desired outcome.
I have submitted a PR to the node-fs-routes repo that fixes this. https://github.com/jsdevel/node-fs-routes/pull/2
This will reduce boilerplate.
I was trying to do a PUT /inventories/{id} endpoint that will accept request body as:
{ "inventory": 100 }
I defined the apiDoc in each path js file, and this is the one for PUT.
// paths/inventories/{id}.js
const inventoryByIdPath = (inventoriesService) => {
const PUT = (req, res) => {
const id = _.get(req, 'params.id');
const data = _.get(req, 'params.data');
...
};
PUT.apiDoc = {
...
parameters: [
{
in: 'path',
name: 'id',
description: 'productId',
required: true,
type: 'string'
},
{
in: 'body',
name: 'data',
description: 'Inventory Data',
required: true,
schema: {
$ref: '../../configs/schemas.json#/Inventory'
}
}
]
...
}
// schemas.json:
{
"Inventory": {
"properties": {
"inventory": {
"type": "number"
}
}
}
}
However, when I call this endpoint, it will always return html error response instead of json:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Error</title>
</head>
<body>
<pre>[object Object]</pre>
</body>
</html>
and console would have logged: [object Object]
after I send the request, which I didn't log it anywhere in code.
After setting the break point, I found out it didn't even make it to the line: const PUT = (req, res) => {...}
Though after removing:
{
in: 'body',
name: 'data',
description: 'Inventory Data',
required: true,
schema: {
$ref: '../../configs/schemas.json#/Inventory'
}
}
It would work normal, but it won't have 'body' in req.
I tried to find more similar examples online, but only found those provided in express-openapi docs.
Having no clue where would it go wrong. Any ideas? And is there anyway I could know what's inside that mystery [object, Object]?
Using these packages:
{
"express": "^4.16.2",
"express-openapi": "^1.2.0"
}
'x-express-openapi-additional-middleware': [myMiddleware]
.
The middleware should be appended after coercion, defaults, and validation middleware, but not after operation middleware.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.