npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

payment-microservice

v2.1.0

Published

Payment micro-service package

Downloads

115

Readme

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>;
}