@studiohyperdrive/swagger-express-ts
Register API endpoints and operations using TypeScript Decorators and generate Swagger Documentation automatically for your express application.
Table of contents
Getting Started
Install the package
# NPM
npm install --save @studiohyperdrive/swagger-express-ts
# Yarn
yarn add --save @studiohyperdrive/swagger-express-ts
Usage
See the demo
folder for a working example.
1. Create a router for your api:
import {
ApiPath,
Router,
} from '@studiohyperdrive/swagger-express-ts';
@ApiPath({
path: '/demo',
version: 1,
description: 'Demo api',
})
class DemoV1Router extends Router {}
2. Add some definitions:
import {
ApiDefinition,
SwaggerApiDefinitionProperties,
SwaggerModelType,
} from '@studiohyperdrive/swagger-express-ts';
...
class DemoV1Router {
@ApiDefinition({
type: SwaggerModelType.OBJECT,
description: 'Thing',
})
public static Thing: SwaggerApiDefinitionProperties = {
count: {
type: SwaggerModelType.NUMBER,
description: 'count',
required: true,
example: 10,
},
};
@ApiDefinition({
type: SwaggerModelType.OBJECT,
description: 'Item',
})
public static Item: SwaggerApiDefinitionProperties = {
foo: {
type: SwaggerModelType.STRING,
description: 'bar',
required: true,
example: 'stuff and things',
},
thing: {
type: SwaggerModelType.OBJECT,
model: 'Thing',
example: {},
},
};
}
3. Register an operation:
import {
ApiOperationGet,
SwaggerResponseType,
SwaggerUtils,
} from '@studiohyperdrive/swagger-express-ts';
...
class DemoV1Router {
@ApiOperationGet({
description: 'Get all items',
responses: {
200: {
description: 'OK',
type: SwaggerResponseType.ARRAY,
model: 'Item'
},
},
})
public getItems(app: Application): void {
app.route(this.baseUrl).get(
SwaggerUtils.createController((req, res, next) => {
return {
total: 1,
pages: 1,
page: 1,
size: 20,
items: [{
foo: 'bar',
thing: {
count: 2,
},
}],
};
})
);
}
}
4. Use the middleware to serve your docs
import express from 'express';
import { swaggerExpress } from '@studiohyperdrive/swagger-express-ts';
const app = express();
app.use(swaggerExpress({
docsPath: '/docs',
basePath: '/',
info: {
version: '1.0.0',
title: 'My custom API',
},
host: 'localhost:3000',
uiOptions: {
customFavIcon: 'https://link.to.my/favicon.ico',
},
}));
The docs will be available on the url you configured. For the example above that would be:
# [host]/[docsPath]
http://localhost:3000/docs
You can filter endpoints by API version:
# [host]/[docsPath]/[version]
http://localhost:3000/docs/v1
Or view the swagger spec as a json file:
# [host]/[docsPath]/json
http://localhost:3000/docs/json
Decorators
There are 7 decorators you can use:
-
@ApiDefinition
: register a Swagger schema -
@ApiPath
: register a new API base path -
@ApiOperationGet
: register a GET operation -
@ApiOperationPost
: register a POST operation -
@ApiOperationPut
: register a PUT operation -
@ApiOperationPatch
: register a PATCH operation -
@ApiOperationDelete
: register a DELETE operation
Utils
createController
The createController
util has 2 main functions:
- Wrap your controller in a try/catch block and properly handle errors.
- Remove the boilerplate of returning data.
import { Request, Response, Next, SwaggerUtils } from '@studiohyperdrive/swagger-express-ts';
const controller = async (req: Request, res: Response, next: Next): Promise<Items> => {
return await fetchThings(req.params);
};
SwaggerUtils.createController(controller);
Any value you return will be send back to the client as a JSON response with status 200. Errors will be handled by the global error handling.
extractVersion
The extractVersion
util can be used to extract the version (number) from a number or string input:
import { SwaggerUtils } from '@studiohyperdrive';
SwaggerUtils.extractVersion(1); // = 1
SwaggerUtils.extractVersion('1'); // = 1
SwaggerUtils.extractVersion('v1'); // = 1
SwaggerUtils.extractVersion(); // = null
SwaggerUtils.extractVersion('test'); // = null
getBaseUrl
The getBaseUrl
util can be used to get a base url from a path and/or version input:
import { SwaggerUtils } from '@studiohyperdrive';
SwaggerUtils.getBaseUrl({ version: 1, path: '/demo' }); // = /v1/demo
SwaggerUtils.getBaseUrl({ path: '/demo' }); // = /demo
SwaggerUtils.getBaseUrl({ version: 'test', path: '/demo' }); // = /demo
paginated
The paginated
util can be used to get a paginated Swagger response:
import { SwaggerUtils } from '@studiohyperdrive';
SwaggerUtils.paginated('Item', 'Item description');
{
description: 'Paginated result',
type: 'object',
properties: {
items: {
model: 'Item',
description: 'Item description',
type: 'array',
},
total: {
type: 'number,
required: true,
example: 76,
},
pages: {
type: 'number,
required: true,
example: 4,
},
page: {
type: 'number,
required: true,
example: 1,
},
size: {
type: 'number,
required: true,
example: 20,
},
}
}