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 CerberusRequest
new 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: EventType
CONNECTION
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 CerberusRequest
new 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 userID
var 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-cache
getCacheKey
: 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 getCacheKey
getCacheKey
: 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 timeframe
timeframe
(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