payment-microservice

2.1.0 • Public • Published

Payment Microservice

Description

This package is meant to be a wrapper for micro-services running on an express server and using sockets for point to point connection. It has been developed specially to implement payment micro-services, but it can be used for any kind of micro-service.

When using this package, you won't need to worry about initializing express, or the socket communication interface.

Usage

There are two ways of using this package, depending on the type of deployment of the applications or websites that will connect to it.

If your application is using kubernetes and has more than one instance you will need to use the redis implementation.

To do this you only have to import and call the connectRedis function:

import { connectRedis } from 'payment-microservice';

Parameters

Parameter Type Type Description Description Optional
redisConnection Object RedisConnectionData Object with the redis connection host name and port info No
connectFn Function (hostname: string) => void Function which will be executed on socket connection No
statusFn Function (req: express.Request,res: express.Response) => Promise<express.Response> Status Function. It will run on the /status endpoint and it should check that everything needed for the micro-service is running. For example, check if the database is up. No
port number -- Port in which the micro service will run. No
mongoURL string -- Connection URL to the micro services' Mongo database. No
mongoDBName string -- Name of the database. No
microName string -- Micro service name. Used for logs. No
mongoDBOptions Object MongoClientOptions Options passed to the MongoClient connect options Yes
aliveInterval number -- Interval in which an alive event will be issued by the socket. Defaults to a minute. Yes
handlers Object Handler[] Array of handlers to be exposed by the express server. Yes

Example:

connectRedis(
    getRedisServer(),
    connectRedisFn,
    status,
    3002,
    config.mongoURL,
    config.mongoDBName,
    'PayPal',
    undefined,
    undefined,
    callbacks,
  );
};

Socket Interface

The package exposes a socket interface on the /ws path. It will create a socket server, to create a room with hostname() as name, so every pod has a different room name, and a socket client which will join to that room. The socket server will use a redisAdapter with the host name and port provided.

When the socket client connects to the server it will join the room, and the socket server will set an interval (using the aliveInterval parameter) in which it will emit an alive event with the room id and the micro service name.

    socketServer.emit('alive', { id: CUSTOM_ROOM, name: microName });

This event should be listened by the application to know which room to send the messages for the micro service.

To make something similar to REST calls to the socket rooms you can use the methodWrapperRedis function, which will receive the socket event as a string and the method to execute when this event is called. This method should be of type APIFunctionInterfaceRedis<ReturnType>.

async function methodWrapperRedis<ReturnType>(
  methodName: string,
  targetMethod: APIFunctionInterfaceRedis<ReturnType>,
): Promise<void>{...}

This methodWrapper should be used on the connectFn passed to connectRedis. Example:

const connectRedisFn = (hostName: string): void => {
  out.info(`Executing PayPal connect function on host name: ${hostName}`);
  Socket.methodWrapperRedis<void>('setKeys', setKeysSocket);
  Socket.methodWrapperRedis<void>('createPayment', createPaymentSocket);
  Socket.methodWrapperRedis<void>('updatePayment', updatePaymentSocket);
  Socket.methodWrapperRedis<void>('cancelPayment', cancelPaymentSocket);
};

Example of a method passed in the targetMethod parameter:

const setKeysSocket: Socket.APIFunctionInterfaceRedis<void> = async (
  room,
  data,
) => {
  out.info(colors.blue.bold(`Room ${colors.white.bold(room)} called setKeys`));

  setKeys(data as SetKeysInfo);
};

This methods should always receive the room name and an object with parameters.

After setting up the method wrappers, we will use the executeToRoom method to call them. This method will emit the event and wait for the response using a unique id.

function executeToRoom<ReturnType>(
  room: string,
  name: string,
  params?: object,
): Promise<ReturnType> {...}

This method receives the room name where it will emit the event, the name of the event and the params that the event targetMethod will receive.

Example call:

await Socket.executeToRoom<void>(ROOM_NAME, EVENT_NAME, params);

We can import all this methods like this:

import Socket from 'payment-microservice/Socket';

Handlers

The micro service will always expose two default handlers:

  • /: will always return a status 200 with an OK if the service is up and running.
  • /status: It will execute the statusFn passed by parameter. This function should check if everything that the micro service needs is working (database, external APIs...) and return a 200 with OK: true, or a 500 with OK: false and error information.

We can also supply an array of Express handlers on the handlers optional parameter.

Every object of this array will contain the handler's route and the method to be called, which will have the same structure as the status method.

Example:

const webhookCallback = async (
  req: express.Request,
  res: express.Response,
): Promise<express.Response> => {...}

const callbacks = [{ route: '/cb', handler: webhookCallback }];

DbPool

The micro service package will also handle Mongo database connection and offer a DbPool to perform operations on the provided database.

You can import this DbPool from:

import dbPool from 'payment-microservice/DbPool';

To retrieve the database connection you will only need to call the getConnection() method.

const db = await dbPool.getConnection();

The connectRedis method will initialize the DbPool with the URL and the database name provided, but it can be re-initialized manually using the init method.

dbPool.init(config.mongoURL, config.mongoDBName);

Utils

This package also exports some logger utils so you don't have to duplicate dependencies. You can import a Winston logger from:

import out from 'payment-microservice/Out';

and colors from:

import colors from 'payment-microservice/Colors;'

Types

  • RedisConnectionData:

    interface RedisConnectionData {
    host: string;
    port: number;
    }
  • Handler:

    interface Handler {
    route: string;
    handler: (req: express.Request,res: express.Response) => Promise<express.Response>
    }
  • APIFunctionInterfaceRedis:

interface APIFunctionInterfaceRedis<ReturnType> {
  (hostname: string, ...params: (string | object)[]): Promise<ReturnType>;
}

Readme

Keywords

none

Package Sidebar

Install

npm i payment-microservice

Weekly Downloads

0

Version

2.1.0

License

ISC

Unpacked Size

50.4 kB

Total Files

29

Last publish

Collaborators

  • mgonand
  • alber0905