1.0.3 • Published 4 months ago
@showroomprive/koa-swagger v1.0.3
@showroomprive/koa-swagger
A library to configure Swagger for koa.js API. It provides tools for
- Auto-discovery in Koa.js routes for the application based on files suffix
- Auto-registry Koa.js routes for swagger on files suffix
Table of Contents
Dependencies
Dependency | Version |
---|---|
koa-router | ^13.0.1 |
Dev Dependencies
Dependency | Version |
---|---|
@types/jest | ^29.5.14 |
@types/koa-router | ^7.4.8 |
@types/node | ^22.13.9 |
jest | ^29.7.0 |
jest-junit | ^16.0.0 |
ts-jest | ^29.2.6 |
ts-node | ^10.9.2 |
typescript | ^5.8.2 |
Installation
To install the package, run:
npm install @showroomprive/koa-swagger
Configuration
Auto registry routes for Koa.js
After create the koa application we can use the autoloader based on routes folder and routes extension.
import { routesAutoLoader } from '@showroomprive/koa-swagger/dist/utils/routeScanner';
import { createSwaggerSpec } from '@showroomprive/koa-swagger/dist/docs/swagger';
const app = new Koa();
const routesPath = path.join(__dirname, 'routes'); /** folder where the routes files are **/
const routeSuffix = 'routes'; /** file extension eg: hello.routes.ts **/
const swaggerSpec = createSwaggerSpec("Title", '3.0.0', 'Description', router, routesPath, routeSuffix);
app.use(router.routes()).use(router.allowedMethods());
router.get('/swagger.json', (ctx) => {
ctx.body = swaggerSpec;
});
app.use(
koaSwagger({
routePrefix: '/swagger', // Swagger UI available at /swagger
swaggerOptions: { spec: swaggerSpec },
})
);
const PORT = process.env.PORT ?? 3000;
app.listen(PORT, () => {
console.log(`Server running on http://localhost:${PORT}`);
console.log(`Swagger UI available at http://localhost:${PORT}/swagger`);
console.log(`Swagger JSON available at http://localhost:${PORT}/swagger.json`);
});
This will configure auto registry for routes for the koa.js app and for the swagger.
Usage
Add metadata
To add metadate (body request for exemple), we can fine property in our route files (should be named : routeMetadata
), here is the definition :
export interface RouteMetadata {
path: string;
method: 'get' | 'post' | 'put' | 'delete' | 'patch';
description: string;
groupName: string;
requestBody?: RouteRequestBody;
parameters?: {
name: string;
in: 'query' | 'path' | 'header' | 'cookie';
required: boolean;
schema: {
type: string;
};
description: string;
}[];
responses: RouteResponse;
}
Example of route
import Router from 'koa-router';
import HelloController from '../controllers/hello.controller';
const router = new Router({
prefix: '/hello',
});
/******************/
router.get('/', HelloController.getHello);
export default router;
import { Context } from 'koa';
export default class HelloController {
static async getHello(ctx: Context) {
ctx.body = { message: 'Hello world' };
}
}
/******************/
import Router from 'koa-router';
import GreetingsController from '../controllers/greetings.controller';
const router = new Router({
prefix: '/greetings',
});
// Define routes
router.get('/', GreetingsController.getGreetings);
router.post('/', GreetingsController.postGreetings);
// Route metadata for Swagger
export const routeMetadata = [
{
path: '/greetings',
method: 'get',
description: 'Get Greetings',
groupName: 'Greetings',
responses: {
200: {
description: 'Greetings message',
content: {
'application/json': {
schema: {
type: 'object',
properties: {
message: { type: 'string' },
config: { type: 'string' },
},
},
},
},
},
},
},
{
path: '/greetings',
method: 'post',
description: 'Post Greetings',
groupName: 'Greetings',
requestBody: {
description: 'Request body for posting greetings',
required: true,
content: {
'application/json': {
schema: {
type: 'object',
properties: {
name: { type: 'string' },
},
required: ['name'],
},
},
},
},
responses: {
200: {
description: 'Response for posting greetings',
content: {
'application/json': {
schema: {
type: 'object',
properties: {
message: { type: 'string' },
config: { type: 'string' },
},
},
},
},
},
},
},
];
export default router;
/******************/
import { Context } from 'koa';
import { summary, body, request } from 'koa-swagger-decorator';
export default class GreetingsController {
static async getGreetings(ctx: Context) {
ctx.body = { message: 'Greetings world' };
}
@request('post', '/greetings')
@summary('Post Greetings')
@body({
name: { type: 'string', required: true, example: 'John' }
})
static async postGreetings(ctx: Context) {
const { name } = ctx.request.body as { name: string };
ctx.body = { message: `Greetings, ${name}` };
}
}