express-zoa-server
z-openapi
z-openapi can help you create swagger definition.
From a Zopenapi
instance, each component and subcomponent are fluents.
You can describe them either with a plain javascript object, either with a factory function who takes and returns a fluent builder instance.
Some components have helpers functions to help saving time.
eg: <Schema instance>.string(true)
for <Schema instance>.type('string').required(true)
Typescript hint enabled ! Yeay ! Let's dive into it !
In a Node project install z-openapi
$ npm install --save z-openapi
At some point in your code, import Zopenapi
class, and export an instance for other modules to enhance it.
import { Zopenapi } from 'z-openapi';
export const zoa = new Zopenapi();
Describe top level informations
zoa
.info(info => info // this is the builder instance
.title('Swagger title')
.version('1.0.0')
.description('Swagger description')
// Same for each compnt / subcompnt:
// Equivalent
// .license({ name: 'ISC' }) // plain openapi object
.license(license => license.name('ISC')) // factory function
.contact(contact => contact
.name('Swagger contact name')
.email('Swagger contact email')
.url('Swagger contact url')
)
)
.servers(
{ url: 'http://localhost:3000' },
{ url: 'https://another-hostname.com' },
)
.components(components => components
.schemas({
BaseError: baseError => baseError.object({
name: name => name.string(true).description('Swagger schema description'),
message: message => message.string(true),
}).description('Swagger schema description'),
})
.securitySchemes({
bearer: bearer => bearer.name('Authorization').in('header'),
apikey: apikey => apikey.name('api-key').in('query'),
})
.
);
/*
.
.
.
*/
Add more schemas in your model's modules
zoa.componentsSchemas({
User: user => user.object({
id: id => id.string(),
email: email => email.string(true),
password: password => password.string(),
}),
Users: users => users.array(items => items.ref('User')),
CreateUser: user => user.object({
email: email => email.string(true),
password: password => password.string(true),
}),
UpdateUser: user => user.object({
email: email => email.string(),
password: password => password.string(),
})
});
Add paths in your router's modules
zoa.paths({
'/users': path => path
.get(get => get
.response200(resp => resp.jsonSchema(json => json.ref('Users')))
.security({ bearer: [] })
)
.post(post => post
.requestBody(body => body.jsonSchema(json => json.ref('CreateUser')))
.response200(resp => resp.jsonSchema(json => json.ref('User')))
.security({ apikey: [] })
),
'/users/{id}': path => path
.get(get => get
.parameters(param => param.name('id'))
.response200(resp => resp.jsonSchema(json => json.ref('User')))
.security({ bearer: [] })
)
.put(put => put
.parameters(param => param.name('id'))
.requestBody(body => body.jsonSchema(json => json.ref('UpdateUser')))
.response200(resp => resp.jsonSchema(json => json.ref('User')))
.security({ bearer: [] })
)
.delete(del => del
.parameters(param => param.name('id'))
.response200(resp => resp.jsonSchema(json => json.ref('User')))
.security({ bearer: [] })
)
});
Finnaly, to get it serve by swagger-ui
import swaggerUi from 'swagger-ui-express';
/*
.
.
.
*/
app.use('/docs', swaggerUi.serve, swaggerUi.setup(zoa.js()));