Implementation of IBackend
The AMQP Backend is used to communicate with your other backend services using RPC over a message queue
new AMQPBackend(amqpURI, replyExchange, rpcQueue)amqpURI (string): URI used to connect to the message queuereplyExchange (string): Name of the exchange to listen for replies onrpcQueue (string): Queue to send requests onvar b = new AMQPBackend("amqp://SOME_IP:2345", "cerberusResponse", "rpcQueue")
Backend Interface
enable(sendResponse)Called by Cerberus.addFrontend when this backend is enabled
sendResponse (SendResponse)handleConnection(connection)Optional function that is called when a frontend receives a new connection
connection (CerberusConnection)handleRequest(request)Handle a request and send a response using sendResponse
request (CerberusRequest)Implementation of IBackend
The HTTP Backend is used to communicate with your other backend services via HTTP requests
new HTTPBackend(generateRequestOptions)generateRequestOptions: generate options for the request node library given a CerberusRequestnew HTTPBackend((req) => ({
url: "https://some-internal-host:4032",
method: "POST",
json: {
user: req.connection.userID,
data: req.data.color,
},
}))
Implementation of IBackend
The ZMQ Backend is used to communicate with your other backend services using ZeroMQ
new ZMQBackend(zmqPushURI, zmqSubURI)zmqPushURI (string): URI to connect to a ZMQ push socketzmqSubURI (string): URI to connect to a ZMQ sub socketnew ZMQBackend("tcp://SOME_IP:2345", "tcp://SOME_IP:2346")
Enum: EventTypeCONNECTION
REQUEST
RESPONSE
The main Cerberus class
new Cerberus()var c = new Cerberus()
addFrontend(frontend)Adds a frontend
frontend (IFrontend)var c = new Cerberus()
// Add a Websocket frontend
c.addFrontend(new WSFrontend(8080))
// Add a HTTP frontend
// `location.query` is what we want to store
c.addFrontend(new HTTPFrontend(8081, false, (httpReq, location) => location.query))
addPlugin(plugin, eventType)Adds a plugin. If a plugin contains multiple handlers, you will need to add the plugin once for every handler. For example, if a plugin needs to run during both requests and responses, you will need to add it once to the request chain and once to the response chain. Note: The order in which plugins are added is the order in which they are executed.
plugin (IPlugin)eventType ("connection" | "request" | "response")var latencyMeasurement = ... // Some plugin
c.addPlugin(latencyMeasurement, "request")
// Add other plugins
c.addPlugin(latencyMeasurement, "response")
on(type, middleware)Run an EventHandler when an event fires
type ("connection" | "request" | "response")middleware (EventHandler)var c = new Cerberus();
c.on('request', function(request) {
// Do something
})
c.on('response', function(response) {
// Do something
})
c.on('connection', function(connection) {
// Do something
})
setBackend(backend)Sets the backend
backend (IBackend)Frontend Interface
enable(createConnection, sendRequest)Called by Cerberus.addFrontend when this frontend is enabled
createConnection (CreateConnection)sendRequest (SendRequest)Implementation of IFrontend
HTTPFrontend starts a HTTP server on a specified port
new HTTPFrontend(port, allowForwadedFor, getDataFromRequest)port (number): The port to run the server onallowForwadedFor (boolean): Whether or not to look at IP addresses in the x-forwarded-for headergetDataFromRequest: A function that returns data to store in a CerberusRequest given a HTTP requestvar c = new Cerberus()
// Add a HTTP frontend
// `location.query` is what we want to store
c.addFrontend(new HTTPFrontend(8081, false, (httpReq, location) => location.query))
Implementation of IFrontend
WSFrontend starts a Websocket server on a specified port
new WSFrontend(port, allowForwadedFor)port (number): The port to run the server onallowForwadedFor (boolean): Whether or not to look at IP addresses in the x-forwarded-for headervar c = new Cerberus()
// Add a Websocket frontend
c.addFrontend(new WSFrontend(8080, false))
Implementation of IPlugin
A plugin that logs the time between a request and the corresponding response.
new LatencyLogger(maxNumConcurrentRequestsToTrack, maxRequestAge, getRequestMethodName)maxNumConcurrentRequestsToTrack (number): The max number of requests that can be tracked at a timemaxRequestAge (number): The longest request that can be tracked (in ms)getRequestMethodName: Function to get the name to be logged given a CerberusRequestnew LatencyLogger(500, 1000, (req) => req.data.method)
Implementation of IPlugin
A plugin that validates a HMAC signed token when a new connection is established.
This is compatible with signed cookies from Express (https://github.com/expressjs/cookie-parser)
When the authenticator receives a CerberusRequest object, it sets the userID
field in the request if the token is valid
new HMACAuthenticator(key, queryParamName, shouldErrorOnInvalidToken)key (string): The key that the token should be signed withqueryParamName (string): The name of the query parameter where the token is storedshouldErrorOnInvalidToken (boolean): Whether or not connections with invalid tokens should
throw an error be closed. If this is false, unsigned requests won't have a valid userIDvar c = new Cerberus()
c.addPlugin(new HMACAuthenticator("SUPER_SECRET_HMAC_KEY", "token", false))
Implementation of IPlugin
A plugin to cache specific requests and responses in an in-memory LRU cache.
new LRUCache(cacheParams, getCacheKey)cacheParams (object): Params to pass into lru-cachegetCacheKey: A function to get cache keys given a request. Can return null if you do
not want to cache the response to a given request// Use the location as the cache key
var cachePlugin = new LRUCache({max: 5000, maxAge: 60 * 60 * 1000}, (request) => request.data.location)
// Build request pipeline
c.addPlugin(cachePlugin, "request")
// Add other stuff
// Build response pipeline
c.addPlugin(cachePlugin, "response")
Implementation of IPlugin
A plugin to cache specific requests and responses in Redis. This is useful for sharing a cache between multiple Cerberus instances.
new RedisCache(hostname, port, redisCachePrefix, getCacheKey)hostname (string): Redis hostname or IP addressport (number): Redis portredisCachePrefix (string): Prefix to add to cache keys returned by getCacheKeygetCacheKey: A function to get cache keys given a request. Can return null if you do
not want to cache the response to a given request// Use the location as the cache key
var cachePlugin = new RedisCache("127.0.0.1", 6379, "", (request) => request.data.location)
// Build request pipeline
c.addPlugin(cachePlugin, "request")
// Add other stuff
// Build response pipeline
c.addPlugin(cachePlugin, "response")
Note: at least one of the handle methods in this interface must be implemented
Each handler can return one of the following:
Connection and request handlers can also return these:
handleConnection(connection)Optional function that is called when Cerberus receives a new connection
connection (CerberusConnection)handleRequest(request)Optional function to handle requests
request (CerberusRequest)handleResponse(response)Optional function to handle responses
response (CerberusResponse)setResponseSender(sendResponse)If a plugin ever wants to send a response, it can get a function to do so by implementing this function. This is useful in caching plugins
sendResponse (SendResponse)Implementation of IPlugin
A configurable rate limiter for requests based on IP address.
new RateLimit(numRequests, timeframe, shouldRateLimit)numRequests (any): The number of requests allowed in timeframetimeframe (any): The timeframe in ms for the rate limitshouldRateLimit: A function that takes a CerberusRequest and returns whether or
not to count the request against the rate limit.var c = new Cerberus()
// Limit all calls to 10 requests per second per IP address
c.addPlugin(new RateLimit(10, 1000, () => true))
CerberusConnection is a standardized representation of a connection to Cerberus
new CerberusConnection(sendFn, closeFn, headers, location, ipAddr)sendFn (ConnectionSendFunction): A function that sends data on the connectioncloseFn (ConnectionCloseFunction): A function that closes the connectionheaders (object): Headerslocation (Url): Output of uri.parseipAddr (string): Remote IP addressRequest is a standardized representation of a request to Cerberus
new CerberusRequest(connection, data)connection (CerberusConnection): The connection that this request originated fromdata (object): Data for this requestResponse is a standardized representation of a response in Cerberus
new CerberusResponse(connection, data, requestID)connection (CerberusConnection): The connection that this response should be sent ondata (object): Data for this response. Should be able to stringify using JSON.stringifyrequestID (RequestID): The RequestID for the request corresponding to this response