Create an API
Create an fast and easy to use API using AbyssMonitor features
AbyssMonitor provide tools to setup an easy API with NodeJS and TypeScript. Tools are designed to works with Express.
Setup
Create your first Middleware
import { Request, Response, NextFunction } from 'express';
import * as contentType from 'content-type';
import { IMonitorLocals, Logger, Middleware } from '@abyss-project/monitor';
export const ALLOWED_REQUEST_TYPES = [
'application/json',
'multipart/form-data',
'application/x-www-form-urlencoded',
];
@Middleware()
export default class MyMiddleware {
private static readonly logger = new Logger({});
public async run(
req: Request,
res: Response<unknown, IMonitorLocals>,
next: NextFunction,
): Promise<void> {
if (req.headers['content-type']) {
const contentT = contentType.parse({ headers: req.headers });
if (!ALLOWED_REQUEST_TYPES.includes(contentT.type)) {
// Throw an error because invalid request type
}
}
next();
}
}
Create your first Controller
import { Request, Response } from 'express';
import { Controller, Get, IMonitorLocals, Logger, Middlewares } from '@abyss-project/monitor';
import MyMiddleware from './../middlewares/my-middleware.middleware.ts'
@Controller({ prefixPath: '/' })
@Middlewares([MyMiddleware])
export default class MyController {
private static readonly logger = new Logger({});
@Get({
path: '/hello-world',
})
@Middlewares([])
async helloWorld(
req: Request<Record<string, never>, string, void>,
res: Response<string, IMonitorLocals>,
): Promise<void> {
res.send(`Hello world !`);
}
}
Create the Express Application
import {
IMonitorLocals,
contextMiddleware,
controllerLoader,
loggerEndpointMiddleware,
loggerSetupMiddleware,
Logger,
} from '@abyss-project/monitor';
import express, { Response, Request, NextFunction, Router } from 'express';
import { json, urlencoded } from 'body-parser';
import cors from 'cors';
import cookieParser from 'cookie-parser';
import helmet from 'helmet';
import compression from 'compression';
import swaggerUi from 'swagger-ui-express';
import MyController from './controllers/my-controller.controller.ts';
import MyMiddleware from './middlewares/my-middleware.middleware.ts';
require('express-async-errors');
const PREFIX = '/api';
const PORT = 5000;
const apiLogger = new Logger({
shouldDisableRemoteLogging: process.env.NODE_ENV === 'DEVELOPMENT',
});
const init = async (): Promise<express.Application> => {
const app = express();
// Adding the ContextMiddleware
app.use(contextMiddleware);
// Disabling the PoweredBy Express header
app.disable('x-powered-by');
// Enabling CORS and set kind of request my API will accept because
// I want to make this API public
app.use(cors());
app.use((req: Request, res: Response<unknown, ILocals>, next: NextFunction) => {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader(
'Access-Control-Allow-Headers',
'Origin, X-Requested-With, Content, Accept, Content-Type, Authorization',
);
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, PATCH, OPTIONS');
res.setHeader('Access-Control-Expose-Headers', 'Content-disposition, filename');
next();
});
app.use(urlencoded({ extended: true }));
app.use(json());
app.use(cookieParser());
app.use(helmet());
app.use(compression());
// Setting logger middleware
app.use(loggerSetupMiddleware);
app.use((req, res: Response<unknown, IMonitorLocals>, next) =>
loggerEndpointMiddleware(apiLogger, req, res, next),
);
// Setting up the swagger
const {
swagger: { tags, paths },
} = await controllerLoader(app, {
prefix: PREFIX,
router: Router,
middlewares: [MyMiddleware],
controllers: [MyController],
});
app.use(
(error: Error, _req: Request, _res: Response<unknown, IMonitorLocals>, _next: NextFunction) => {
// Do what you want with the error
apiLogger.error(error);
},
);
app
.listen(PORT, () => {
apiLogger.info(`API started on port ${PORT}`);
})
.on('error', (error) => {
apiLogger.error(`API failed to start. Error: ${error}`);
});
const defaultSwagger = {
openapi: '3.0.3',
info: {
title: 'My First API',
description: '',
version: '1.0',
termsOfService: 'http://swagger.io/terms/',
contact: {
email: 'apiteam@swagger.io',
},
license: {
name: 'Apache 2.0',
},
url: 'http://www.apache.org/licenses/LICENSE-2.0.html',
},
produces: ['application/json'],
host: `http://localhost:${PORT}`,
basePath: PREFIX,
tags,
paths,
};
app.use(
'/swagger',
(req: Request, res: Response<unknown, IMonitorLocals>, next: NextFunction) => {
// Disabling the log on swagger endpoint to not spam with useless logs
res.locals.shouldNotPublishLog = true;
next();
},
swaggerUi.serve,
// eslint-disable-next-line @typescript-eslint/no-var-requires
swaggerUi.setup(defaultSwagger),
);
return app;
};
await init();
Last updated