express-mod
v1.2.10
Published
express-mod is an open source library for building API (Application programming interface)
Downloads
89
Maintainers
Readme
About
express-mod is an open source library for building API (Application programming interface)
express-mod
is based on the express framework.
Features ✨
OOP
andMVC
based routing or functionality are also supported ✔- Route validation ✔
- Error handler such as 404 exception and global exception ✔
- Server crashes such as
bugs
,errors
are no longer a problem.
- Server crashes such as
- Catch async error on all routes ✔
- No more trycatch blocks when dealing with async functions.
- Typescript support out of the box ✔
All these features are included by default, they can save you the time of setting them up from scratch.
👉 Note: some of these features are optional. You can either use or not to use.
Do's and Don'ts of express-mod
express-mod
aims to make Express more manageable using its decorator APIsexpress-mod
does not modify any functions of expressexpress-mod
aims to be fast, lighter, flexible and maintainable- Using
express-mod
with TypeScript is recommended - Using
express-mod
with JavaScript will gain less benifits or consider usingexpress
instead
Table of contents
Example
Attention: Using
express-mod
with TypeScript projects is recommended. If you are using JavaScript see this.
Start the server
./index.ts
import express from 'express-mod'
// initialize express
const app = express()
// listen for connections
app.listen(4000, () =>
console.log('Server is up! visit: http://localhost:4000'),
)
Register route
./index.ts
import express from 'express-mod'
// initialize express
const app = express()
// register route
app.get('/', (_req, res) => {
res.status(200).send('OK')
}) // visit: http://localhost:4000 => OK
// listen for connections
app.listen(4000, () =>
console.log('Server is up! visit: http://localhost:4000'),
)
Routing with decorator
./sevice.ts
import { Injectable } from 'express-mod'
@Injectable()
export class ExampleService {
public helloWorld(): string {
return 'Hello world!'
}
}
./api.ts
import { Api, Get } from 'express-mod'
import { ExampleService } from './sevice'
@Api()
export class ExampleApi {
constructor(private readonly exampleService: ExampleService) {}
@Get()
public helloWorld(): string {
return this.exampleService.helloWorld()
}
}
./route.ts
import express, { Route } from 'express-mod'
import { ExampleApi } from './api'
@Route([ExampleApi], { router: express.Router() })
export class ExampleRoute {}
Attach and register decorated route
./index.ts
import express, { Router } from 'express-mod'
import { ExampleRoute } from './rouue'
// initialize express
const app = express()
// router instance
const router = new Router({ initial: app })
// attach and register decorated route.
router.attach('/api/v1', [ExampleRoute])
async function __main__() {
// TODO: connect to database
// await connect({ uri: 'DB_URI' })
// listen for connections
app.listen(4000, () =>
console.log('Server is up! visit: http://localhost:4000'),
)
}
// execute main
__main__()
Installation
You need nodeJs installed on your OS.
# with npm
npm i express-mod
# installing typescript
1. npm i -D typescript - in this case I'm using npm.
2. npx tsc --init - to create tsconfig.json file.
As we all know, the library uses @decorator
without enabling some additional features. Typescript will complain. You need to enable these additional features of Typescript. In the file
'tsconfig.json' enable these:
{
"experimentalDecorators": true,
"emitDecoratorMetadata": true
}
That's it. well done! see example
Apis
We provide all the Apis that you will need to create a flexible and maintainable application.
@Api
A class defined with methods for handling one or more requests.
- @param
url
url path.
Example
import { Api } from 'express-mod'
@Api()
export class ExampleApi {}
@Method
A specific endpoint for HTTP requests.
- @param
method
http method type. - @param
url
url path. - @param
status
status code.
Possible methods
@Get(), @Post(), @Put(), @Patch(), @Delete()
Example
import { Get } from 'express-mod'
export class ExampleApi {
@Get() // => "/"
// or - @Get("/", 200) => "/"
// or - @Get(200) => "/"
public helloWorld(): string {
return 'hello world!'
}
}
@Middleware
A function which is called before the route handler.
- @param
mids
execute any code.
Example
method middleware
import { Middleware } from 'express-mod'
export class ExampleApi {
@Middleware([
(req, res, next) => {
console.log('mid mounted before route bound.')
next()
},
])
public helloWorld(): string {
return 'hello world!'
}
}
Example
route middleware
import { Middleware } from 'express-mod'
@Middleware([
(req, res, next) => {
console.log('mid mounted before route bound.')
next()
},
])
export class ExampleRoute {}
@Params
A named URL segments that are used to capture the values specified at their position in the URL.
- @param
name
request type.
Possible params
@Req(), @Res(), @Next(), @Params(), @Query(), @Body(), @Cookies(), @Headers(), @Ctx()
Example
import { Req, Request, Body } from 'express-mod'
export class ExampleApi {
public helloWorld(@Req() req: Request, @Body() body: object): string {
// `req.body` regular use.
// instead of `req.body` use `@Body()` param => req.body
return 'hello world!'
}
}
@Validation
Validation middleware. A function which is called before the route handler.
- @param
schema
schema object.
Supported library: zod
Note: With some libraries besides
zod
can also be integrated with routing validation, but you just have to set it up yourself. Our developers are working on it to put everything convenient.
Example
with zod
import { ValidateRequest, Validation } from 'express-mod'
import { object, string } from 'zod'
export class ExampleApi {
@Validation(object<ValidateRequest>({ body: object({ name: string() }) }))
public helloWorld(): string {
return 'hello world!'
}
}
@Route
No description provided.
- @param
Apis
api handlers. - @param
routeOptions
route options.
Example
import express, { Route } from 'express-mod'
@Route([], { router: express.Router() })
export class ExampleRoute {}
@Injectable
The @Injectable()
decorator is used to define metadata object.
Example
./injectable.ts
import { Injectable } from 'express-mod'
@Injectable()
export class ExampleService {
public username(): string {
return 'Bob'
}
}
@Inject
The @Inject()
decorator is used to mark parameter as dependency.
Example
./inject.ts
import { Inject } from 'express-mod'
import { ExampleService } from './injectable'
export class Example {
constructor(
@Inject(ExampleService) private readonly exampleService: ExampleService,
// short version:
private readonly exampleService: ExampleService, // this will auto inject without using the @Inject() decorator.
) {}
public getName(): string {
return exampleService.username()
} // returns "Bob"
}
@Injector
A top-level class used to resolve injector value.
Example
./injector.ts
import { Injector } from 'express-mod'
import { Example } from './inject'
// resolve Example injector value.
const value = Injector.get(Example)
value.username() // Returns "Bob"
Customize
You can customize some Apis according to your needs.
Middleware
Most come with middleware
. It has to be flexible. Sure, we got it!
Example
./mids.ts
import { Middleware, UnauthorizedError } from 'express-mod'
// check if user is not log in.
const Authenticated = () =>
Middleware([
(req, res, next) => {
if (req.isUnAuthenticated()) {
throw new UnauthorizedError('User unauthorized.')
}
},
])
// example usage:
export class ExampleApi {
@Authenticated()
public helloWorld(): string {
return 'hello world!'
}
}
Method
In addition to the 5 common http methods
@Get(), @Post(), @Put(), @Patch(), @Delete()
that we provided, there are some other http methods such asALL, TRACE, HEAD, OPTIONS, etc.
that we didn't provided. you can customize it to your needs.
Example
./api.method.ts
import { METHOD_DECORATOR_FACTORY, PathParams } from 'express-mod'
// head http method
const Head = (url?: PathParams, status: number = 200) =>
METHOD_DECORATOR_FACTORY('head', url, status)
// example usage:
export class ExampleApi {
@Head()
public helloWorld(): string {
return 'hello world!'
}
}
Errors & Exceptions
Customize response
error.
Example
./errors.err.ts
import { CustomError } from 'express-mod'
export class BadRequestError extends CustomError {
public readonly status = 400
public readonly error = 'BAD_REQUEST'
constructor(public readonly message: string) {
super(message)
Object.setPrototypeOf(this, BadRequestError.prototype)
}
}
// example usage:
throw new BadRequestError('Any message.')
Router
The Router
is a top-level class used to attach and register decorated route.
import express, { Router } from 'express-mod'
// initialize express
const app = express()
// router constance
const router = new Router({ initial: app })
// attach and register decorated route.
router.attach('/', [route, ...])
Exception
No description provided.
- @param
message
response message.
Possible errors
CustomError(), UnauthorizedError(), NotFoundError(), ConflictError(), ValidationError(), ForbiddenError()
Example
throw new ConflictError('User is already exist.')
Define injector
The defineInjector
function is used to define metadata object.
Example
import { defineInjector } from 'express-mod'
export class Example {}
// define injector
defineInjector(Example)
Using with Javascript
Attention: Using
express-mod
with Javascript will gain less benefits. But you can still use it or consider usingexpress
instead.
Start the server
To start the server using
Javascript
(CommonJs) you have to make some changes.
./index.js
// CommonJs
const { expressFn } = require('express-mod') // this would work! ✅
// const express = require('express-mod') this will not work!❌
// initialize express
const app = expressFn()
// listen for connections
app.listen(4000, () =>
console.log('Server is up! visit: http://localhost:4000'),
)
Benefit
express-mod build everything Api (Application programming interface) lighter, easier and maintainable.