api-ms-framework
TypeScript icon, indicating that this package has built-in type declarations

1.7.2 • Public • Published

Microservice template

This repository is a typescript NODEJS application that serves as a template for a microservice API instance for the SHELL ON YOU project. It is deployable using docker-compose and is scalable while relying on NGINX loadbalancing.

The routes of the API it is running are stored in the routes folder so that all of them are centralized.

Installation

npm install will install all depencies required for this application.

Build

npm run build will compile typescript files to ES6 javascript files and output them inside the dist folder.

Note : This command will clear the dist folder if one already exists and also copy *.html files in it. if you have other files with a different extensions that you want to add in the compiled code, edit the postbuild script in the package.json file.

Test

npm run test will run jest testing package on all ./tests/**/*.test.ts files.

Start

npm run start will build then executes the server instance

How to contribute

Commit guidelines

https://www.conventionalcommits.org/en/v1.0.0/#summary

Use commitizen commit formats in order to name your commit messages and descriptions in order to automate the changelog generation.

Overview

This microservice template is a framework in which developers can add their features in a pre-established folder and logic structure. The framework is made to be used as a single-purpose component to a Microservice (MS) Architecture application.

Limitations

Because of that, this setup comes with a lot of complexity and limitations compared to a classic Monolithic setup:

  • Difficult to maintain schema coherence across MS components
  • Higher chance of failure during communication between different services
  • Needs to solve network latency and load balancing
  • Complex testing over a distributed environment

Advantages

This framework comes with the advantages of using the flexibility and scalability of Microservices Architecture. If implemented correctly, each component can be developed, tested, deployed and updated independently leading to faster deployment and troubleshooting turnaround times.

It also confines the developers to a set of rules and a predetermined structure with established design patterns, reducing the time needed to adapt to the framework.

Architecture

Route

Route declaration

The template application works with a sectionized logic, so that the developer may declare groups of routes based on their functionnality.

An API section is a group of Routes declared in a TS (or JS) file inside the ./router/sections folder that module.exports an Object of type {[method: string]: Route}.

The framework will automatically retrieve the exported object of the section files inside the section folder. It will not retrieve files in subfolder however.

A Route is an object that contains all the information of a route (expect for its path which is declared in an Section) that the request handler will need. We will talk more about request handling in the Route handling section.

export class Route {
    public handler: Handler
    public requireLogin: boolean
    public requireAdmin: boolean
    public authorizations: RouteAuthorization[]
    public description: string
    public parameters: RouteParameters
    public returns: RouteReturn
}

export class RouteParameters {
    public params: {[name: string]: {required: boolean, type: Object}} = {}
    public body: {[name: string]: {required: boolean, type: Object}} = {}
    public query: {[name: string]: {required: boolean, type: Object}} = {}
}

export class RouteReturn {
    public onSuccess?: RouteReturnType
    public onError?: {[code: number]: RouteReturnType}[]

    public onSuccessToString(): string{return JSON.stringify(this.onSuccess)}
    public onErrorToString(): string{return JSON.stringify(this.onError)}
    public toString(): string{return JSON.stringify(this)}
}

Route handling

The template logic uses Handlers, instead of directly letting the developer create routers and routes, to structure and split the code between 3 parts:

  • The before part is to be used for pre-request operations like parameter checks (e.g. if a parameter is of the right type, of a special format, etc).
  • The during part is the active handling of the request in which the "business logic" takes place.
  • The after part is to be used for post-request operations like response checks or reformatting (e.g. Taking the response from the business logic and wrap it inside an object, or having a database call to report a change)

When a user request arrives, it is first handled by the express package which will route it based on its path and to the corresponding Handler.

A Handler is an interface that is used to implement the three-part logic described above. It basically contains three methods which will be called sequentially in the following order :

  • beforeHandle
  • handleRequest
  • afterHandle

Each method will be provided by the router with request and contextual data (authentification and other middlewares) as well as two types of callback functions: onSuccess and onError (beforeHandle has an additional callback onMalformedRequest).

To make a handler, the developer must implement the HandlerBase class (that contains existing logic for parameter checks from the route data) in another class and instanciate it in the API section route declaration.

In each step, when something goes wrong and the developer wants to return an error, the onError (or onMalformedRequest) callback should be used. Once called, a response with the error information is sent to the client and the request handling is closed (no further step will be taken).

RabbitMQ

RabbitMQ is a Message Broker that transports information from one place to another with the use of message queues. It is a completely different application that runs on its own docker container that is used to communicate between microservices.

This is what the template use it for. In essence, the communication protocol is handled by a RabbitMQ service (in the ./services folder) that provides functions to send and receive message to and from another microservice.

In all exchanges between microservices via the queues, the RabbitMQService which has been implemented in the template uses RabbitMQMessage object put inside the amqplib.Message object (RabbitMQ package) array buffer.

This object used by the service is structured as follow:

export class RabbitMQMessage {
    public origin_ms_name: string
    public origin_host_name: string
    public origin_full_name: string
    public recipient: string
    public operation_type: string
    public correlation_id?: string
    public error?: {
        requeued: boolean,
        code: string,
        content: any
    }
    public payload: any
}

Mail

Package Sidebar

Install

npm i api-ms-framework

Weekly Downloads

1

Version

1.7.2

License

Apache-2.0

Unpacked Size

476 kB

Total Files

129

Last publish

Collaborators

  • joprocorp