Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

V0.0.7 #5

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
},
"homepage": "https://github.com/quizizz/service-communication-wrapper#readme",
"dependencies": {
"axios": "^0.27.2"
"axios": "^0.27.2",
"uuid": "3.0.1"
}
}
80 changes: 62 additions & 18 deletions src/http/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
const QError = require('../helpers/error');
const path = require('path');
const Axios = require('axios');
const uuid = require('uuid/v4');
const { hrtime } = require('node:process');

class HttpCommunication {
name;
Expand All @@ -26,17 +28,33 @@ class HttpCommunication {
this.contextStorage = contextStorage;
}

static getRequestContext(req, customContextValue) {
const start = hrtime.bigint();
return {
traceId: (req.headers && req.headers['x-q-traceid']) ? req.headers['x-q-traceid'] : uuid(),
userId: (req.user && req.user.id)
? String(req.user.id)
: req.headers['x-q-userid']
? req.headers['x-q-userid']
: null,
ab: (req.headers && (req.headers['x-q-ab-route'] || req.headers['X-Q-AB-ROUTE'])) ? req.headers['x-q-ab-route'] || req.headers['X-Q-AB-ROUTE'] : null,
reqStartTime: start,
...customContextValue,
};
}

handleError(params, response) {
const { method, route, request } = params;
if (response.status >= 400) {
if (response.data) {
const { error } = response.data;
throw new QError(error, `${this.name}_internal_service.RESPONSE_ERROR`, {
const { error, errorType = 'server.UKW' } = response.data;
throw new QError(error, errorType, {
service: this.name,
data: response.data,
request,
method,
route,
type: errorType,
}
);
}
Expand All @@ -60,7 +78,18 @@ class HttpCommunication {
return finalURL.toString();
}

async makeReqeust(params) {
populateHeadersFromContext(ctx) {
const customHeaders = {
'X-Q-TRACEID': (ctx && ctx.traceId) ? ctx.traceId : uuid(),
};
if (ctx) {
if (ctx.userId) customHeaders['X-Q-USERID'] = ctx.userId;
if (ctx.ab) customHeaders['X-Q-AB-ROUTE'] = ctx.ab;
}
return customHeaders;
}

async makeRequest(params) {
const { route, method, request } = params;
const requestURL = this.createRequestURL(route, request.query);
let response;
Expand All @@ -69,29 +98,26 @@ class HttpCommunication {
if (requestContext) {
this.axiosConfig.headers = {
...this.axiosConfig.headers,
// select which headers we want to pass and pass them
...this.populateHeadersFromContext(requestContext),
}
}

if (method === 'get') {
response = await Axios.get(
requestURL,
this.axiosConfig,
);
} else {
response = await Axios[method](
requestURL,
request.body || {},
this.axiosConfig,
);
const req = {
method,
url: requestURL,
...this.axiosConfig,
}
if (request.body) {
req['data'] = request.body;
}
response = await Axios(req);

this.handleError(params, response);
return response.data;
}

async post(route, request) {
const data = await this.makeReqeust({
const data = await this.makeRequest({
method: 'post',
route,
request,
Expand All @@ -100,16 +126,34 @@ class HttpCommunication {
}

async put(route, request) {
const data = await this.makeReqeust({
const data = await this.makeRequest({
method: 'put',
route,
request,
});
return data;
}

async patch(route, request) {
const data = await this.makeRequest({
method: 'patch',
route,
request,
});
return data;
}

async delete(route, request) {
const data = await this.makeRequest({
method: 'delete',
route,
request,
});
return data;
}

async get(route, request = {}) {
const data = await this.makeReqeust({
const data = await this.makeRequest({
method: 'get',
route,
request,
Expand Down
38 changes: 32 additions & 6 deletions types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,28 +9,54 @@ export class HttpCommunication {
*/
constructor({ name, axiosConfig, contextStorage } : { name: string, axiosConfig?: AxiosRequestConfig, contextStorage?: any });

/**
* Function to generate the context object
* @param req {Express Request}
* @param customContextValue any custom values that you want to store in the context
* Return extracted values from the req headers and any custom values pass to generate the context object
*/
static getRequestContext(req: any, customContextValue?: Record<string, unknown>): { traceId: string, userId: string, ab: string };

/**
* Http Get Request
* @param route
* @param request
* @param route
* @param request
* @typeParam T - Response type provided by the callee
* @returns Returns response of the get request
*/
get<T>(route: string, request?: { query: Record<string, string> }): Promise<T>;

/**
* Http Put Request
* @param route
* @param request
* @param route
* @param request
* @typeParam T - Response type provided by the callee
* @returns Returns response of the put request
*/
put<T>(route: string, request: { query: Record<string, string>, body: Record<string, unknown> }): Promise<T>;

/**
* Http Delete Request
* @param route
* @param request
* @typeParam T - Response type provided by the callee
* @returns Returns response of the put request
*/
delete<T>(route: string, request: { query: Record<string, string>, body: Record<string, unknown> }): Promise<T>;

/**
* Http Patch Request
* @param route
* @param request
* @typeParam T - Response type provided by the callee
* @returns Returns response of the put request
*/
patch<T>(route: string, request: { query: Record<string, string>, body: Record<string, unknown> }): Promise<T>;

/**
* Http Post Request
* @param route
* @param request
* @param route
* @param request
* @typeParam T - Response type provided by the callee
* @returns Returns response of the post request
*/
Expand Down