node package manager

@npm/spife-ratelimit

spife-ratelimiter

Middleware that adds Token Bucket-style ratelimiting to Spife.

// settings.js:
module.exports.MIDDLEWARE = {
  ['@npm/spife-ratelimiting', {
    redisUrl: 'redis://localhost:6379', // let it connect to redis
    redisClient,                        // (or give it a client)
 
    costHeader: 'npm-cost',             // the "cost" header to use
                                        // for determining how many
                                        // tokens a request took
 
    clock: Date.now,                    // if you would like time to
                                        // move to the beat of a
                                        // different drum
 
    getBucket (spifeRequest) {          // given a request, return
                                        // an object describing its
                                        // token bucket
      return {
        capacity: 100,                  // how many tokens does
                                        // the bucket hold?
 
        interval: 60,                   // in minutes, how long
                                        // does the bucket take to
                                        // fill up?
 
        key: String                     // what should the bucket be
                                        // named?
      }
    }
  }]
}
 
// views.js:
const reply = require('@npm/spife/reply')
const cost = require('@npm/spife-ratelimiter/decorator')
 
module.exports = {
  // a view can declare how much it costs up-front:
  index: cost(index, 5),
  other
}
 
function index (req, context) {
  return 'I cost five tokens!'
}
 
function other (req, context) {
  return reply.header(
    'I cost a hundred tokens sometimes',
    'npm-cost',
    Math.random() > 0.5 ? 100 : 0
  )
}

This is implemented in redis by keeping two keys per bucket: one that tracks the current number of tokens, and one that tracks the last update time. Both keys are expired at interval, and updated atomically using a Lua script.