Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/fastify/fastify-throttle
Throttle the download speed of a request
https://github.com/fastify/fastify-throttle
fastify fastify-plugin throttle throttling
Last synced: 4 months ago
JSON representation
Throttle the download speed of a request
- Host: GitHub
- URL: https://github.com/fastify/fastify-throttle
- Owner: fastify
- License: other
- Created: 2023-07-16T13:02:20.000Z (over 1 year ago)
- Default Branch: master
- Last Pushed: 2024-10-01T21:18:47.000Z (4 months ago)
- Last Synced: 2024-10-04T15:11:56.065Z (4 months ago)
- Topics: fastify, fastify-plugin, throttle, throttling
- Language: JavaScript
- Homepage:
- Size: 359 KB
- Stars: 17
- Watchers: 10
- Forks: 5
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# @fastify/throttle
![CI](https://github.com/fastify/fastify-throttle/workflows/CI/badge.svg)
[![NPM version](https://img.shields.io/npm/v/@fastify/throttle.svg?style=flat)](https://www.npmjs.com/package/@fastify/throttle)
[![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat)](https://standardjs.com/)Throttle the download speed of a request.
## Install
```sh
npm i @fastify/throttle
```## Usage
Register the plugin and, if necessary, pass custom options.This plugin will add an `onSend` hook to the Fastify instance, which will throttle the download speed of the response.
```js
import Fastify from 'fastify'const fastify = Fastify()
await fastify.register(import('@fastify/throttle'), {
bytesPerSecond: 1024 * 1024, // 1MB/s
streamPayloads: true, // throttle the payload if it is a stream
bufferPayloads: true, // throttle the payload if it is a Buffer
stringPayloads: true // throttle the payload if it is a string
})fastify.get('/', (request, reply) => {
reply.send({ hello: 'world' })
})fastify.listen({ port: 3000 }, err => {
if (err) {
throw err
}
console.log('Server listening at http://localhost:3000')
})
```### Options
You can pass the following options during the plugin registration:
```js
await fastify.register(import('@fastify/throttle'), {
bytesPerSecond: 1000, // 1000 bytes per second
streamPayloads: true, // throttle the payload if it is a stream
bufferPayloads: true, // throttle the payload if it is a Buffer
stringPayloads: true // throttle the payload if it is a string
})
```You can define the throttling globally as plugin options or per route options.
The throttle options per route are the same as the plugin options.| Header | Description | Default |
|--------|-------------|---------|
| `bytesPerSecond` | The allowed bytes per second, number or a function | 16384 |
| `streamPayloads` | Throttle the payload if it is a stream | true |
| `bufferPayloads` | Throttle the payload if it is a Buffer | false |
| `stringPayloads` | Throttle the payload if it is a string | false |
| `async` | Set to true if bytesPerSecond is a function returning a Promise | false |Example for setting throttling globally:
```js
const fastify = require('fastify')()await fastify.register(import('@fastify/throttle'), {
bytesPerSecond: 1024 // 1KB/s
})fastify.get('/', (req, reply) => {
reply.send(createReadStream(resolve(__dirname, __filename)))
})fastify.listen({ port: 3000 })
```Example for setting the throttling per route:
```js
'use strict'const fastify = require('fastify')()
await fastify.register(import('@fastify/throttle'))
fastify.get('/', {
config: {
throttle: {
bytesPerSecond: 1000
}
}
}, (req, reply) => {
reply.send(createReadStream(resolve(__dirname, __filename)))
})fastify.listen({ port: 3000 })
```The `bytesPerSecond` option can be a number or a function. The function for `bytesPerSecond` has the following TypeScript definition:
```typescript
type BytesPerSecond = (request: FastifyRequest) => ((elapsedTime: number, bytes: number) => number) | Promise<((elapsedTime: number, bytes: number) => number)>
````request` is the Fastify request object.
`elapsedTime` is the time since the streaming started in seconds.
`bytes` are the bytes already sent.You must ensure that the return value is an integer or `Infinity`.
You could, for example, delay the output by sending 0 for the first 2 seconds by defining
the `bytesPerSecond` like this:```js
const fastify = require('fastify')()await fastify.register(import('@fastify/throttle'))
fastify.get('/', {
config: {
throttle: {
bytesPerSecond: function bytesPerSecondfactory(request) {
// this function runs for every request
const client = request.headers['customer-id']
return function (elapsedTime, bytes) {
return CONFIG[client] * 2 // return a number of xyz
}
}
}
}
}, (req, reply) => {
reply.send(createReadStream(resolve(__dirname, __filename)))
})fastify.listen({ port: 3000 })
```The `bytesPerSecond` function can be a sync function or an async function. If you provide an async function then it will be detected by the plugin. If it is a sync function returning a Promise, you must set the `async` option to `true`, so that the plugin knows that it should await the Promise.
```js
const fastify = require('fastify')()await fastify.register(import('@fastify/throttle'))
fastify.get('/', {
config: {
throttle: {
async: true,
bytesPerSecond: function bytesPerSecondfactory(request) {
// this function runs for every request
const client = request.headers['customer-id']
return Promise.resolve(function (elapsedTime, bytes) {
return CONFIG[client] * 2 // return a number of xyz
})
}
}
}
}, (req, reply) => {
reply.send(createReadStream(resolve(__dirname, __filename)))
})fastify.listen({ port: 3000 })
```
## License
**[MIT](https://github.com/fastify/fastify-throttle/blob/master/LICENSE)**