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 status200
with anOK
if the service is up and running./status
: It will execute thestatusFn
passed by parameter. This function should check if everything that the micro service needs is working (database, external APIs...) and return a200
withOK: true
, or a500
withOK: 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>;
}