1.2.10 • Published 15 days ago

express-mod v1.2.10

Weekly downloads
-
License
MIT
Repository
github
Last release
15 days ago

About

express-mod is an open source library for building API (Application programming interface)

express-mod is based on the express framework.

Features ✨

  • OOP and MVC 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.
  • 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 APIs
  • express-mod does not modify any functions of express
  • express-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 using express 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 as ALL, 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 using express 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.

1.2.9

15 days ago

1.2.10

15 days ago

1.2.8

1 month ago

1.2.7

1 month ago

1.2.6

3 months ago

1.2.5

3 months ago

1.2.4

3 months ago

1.2.3

4 months ago

1.2.2

4 months ago

1.2.1

4 months ago

1.2.0

6 months ago

1.1.9

6 months ago

1.1.8

7 months ago

1.1.7

7 months ago

1.1.6

7 months ago

1.1.5

7 months ago

1.1.4

7 months ago

1.1.3

7 months ago

1.1.2

7 months ago

1.1.1

7 months ago

1.1.0

7 months ago

1.0.0

7 months ago