Configuration: Order of Policies Matter
When working on Auth0, make sure that the order in which you set the pipelines’ policies matches the order in which the policies are listed:
(gateway.config.yaml)
Metrics: Use epimetheus or prom-client Package
You can use either prom-client or epimetheus.
Personally, I found easier to use the epimetheus package in Gateway Express:
'use strict';
const epimetheus = require('epimetheus');
module.exports = function (gatewayExpressApp) {
epimetheus.instrument(gatewayExpressApp, {url: '/metrics'});
};
Something to considered is that some of the metrics display by epimetheus and prom-client differ.
For example, with epimetheus the http request duration are in milliseconds:
http_request_duration_milliseconds{quantile="0.01",method="get",path="/api/",cardinality="one",status="200"} 1
while in prom-client, the http request duration are in seconds:
http_request_duration_seconds_bucket{service="api",instance="api-3432dc43c4-h3eeg",le="0.005",path="/metrics",method="GET",apiVersion="1.0.0",status="200"} 466081
Swagger
Express Gateway use express. I tried different swagger packages; however, the closest results was to display all the endpoints from the admin side of Express Gateway.
Then, I decided to check the code implemented in the restify-swagger-jsdoc and it did the trick. Here is the modified code:
'use strict';
const swaggerJSDoc = require("swagger-jsdoc");
const path = require("path");
const fs = require("fs");
const mime = require("mime-types");
const swaggerUiPath = path.dirname(require.resolve('swagger-ui'));
const publicPath = '/api'.replace(/\/+$/, '');
const swaggerSpec = swaggerJSDoc({
swaggerDefinition: {
info: {
title: 'API documentation',
version: '0.0.1',
description: 'API documentation'
},
host: undefined,
basePath: '/',
schemes: undefined,
tags: []
},
apis: [
'../**/routes/*.js'
]
});
module.exports = function (gatewayExpressApp) {
gatewayExpressApp.get(`${publicPath}/swagger.json`, (req, res) => {
res.setHeader('Content-type', 'application/json');
res.send(swaggerSpec);
});
gatewayExpressApp.get(new RegExp(publicPath + '\/?$'), (req, res) => {
res.setHeader('Location', `${publicPath}/index.html`);
res.sendStatus(302);
});
gatewayExpressApp.get(new RegExp(publicPath + '\/(.*)$'), (req, res) => {
fs.readFile(path.resolve(swaggerUiPath, req.params[0]), (err, content) => {
if (err) {
res.sendStatus(500);
res.send(`File ${req.params[0]} does not exist`);
res.end;
return;
}
if (req.params[0] === 'index.html') {
let jsonFileUrl = `${req.secure ? 'https' : 'http'}`.concat('://').concat(`${req.headers.host}${publicPath}/swagger.json`);
content = new Buffer(content.toString().replace('url = "http://petstore.swagger.io/v2/swagger.json"', `url = "${jsonFileUrl}"`));
}
const contentType = mime.lookup(req.params[0]);
if (contentType !== false) {
res.setHeader('Content-Type', contentType);
}
res.write(content);
res.end();
});
});
};