npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

donkey-gateway

v1.0.6

Published

API Gateway based on static configuration files

Downloads

4

Readme

🐴 Donkey is a configuration based API Gateway

A configuration based gateway with a decent array of features written in TypeScript. Can replace Kong for basic purposes.

Core Features

  • APIs gateway
    • The configuration is based on a TypeScript function called at runtime
    • Match host and URL to upstream using strings or regular expressions
    • Apply middleware by match
    • Apply middleware globally
  • Rate limitation middleware (uses redis)
  • JWT verification middleware (rotating secrets, payload decoding and forwading)
  • CORS headers middleware
  • Remove headers middleware
  • Basic Auth middleware
  • Metadata middleware (can be used to fetch extra data for a user, organization or anything else specific about the request, uses redis)
  • Authentication middleware

Install

npm install donkey-gateway

Use the boilerplace project

If you wish to use Donkey directly, we recommend to use the example project

git clone [email protected]:batiste/donkey-boilerplate.git
cd donkey-boilerplate
docker compose up

Run the dev server locally

You will need a redis server running on localhost

npm install
# on another process, you might need to run the test backend
node tests/backend.js
npm run serve

Or

docker compose up donkey-dev

Or

docker build . -t donkey-dev
docker run -p 3000:3000 donkey-dev

Configuration

APIs configuration in Donkey works with a list of conditional IMatcher. Each IMatcher is taken in order and the hosts and uris fields are tested with the current incoming request. The IMatcher is used for this request if the provided fields match. If no fields are present the IMatcher is always used.

import { createBasicAuthMiddleware } from './middlewares/basicAuth';
import { Config, IMatcher } from './schema';

export function getConfig(): Config {
  const matchers: IMatcher[] = [
    // match the HTTP header Host: loadtest
    {
      hosts: ['loadtest'],
      upstream: 'localhost',
      port: 8000,
      timeout: 3
    },
    // match HTTP header Host: localhost and the /admin/ uri
    {
      hosts: ['localhost:3000'],
      upstream: 'example.com',
      // at least one uris should match. The match is done with startsWith
      uris: ['/admin/'],
      requestMiddlewares: [createBasicAuthMiddleware('admin', '1234')],
    },
    // match any leftover requests
    {
      upstream: 'example.com',
    },
  ]
  return { matchers }
}

IMatcher options

export interface IMatcher {
  /**
   * Upstream domain, with no protocol and no path.
   */
  upstream: string;
  /**
   * Port to use on the upstream. The default is 80.
   */
  port?: number;
  /**
   * List of hosts to match.
   */
  hosts?: (string | RegExp)[];
  /**
   * List of uris to match. String.startsWith is used for the match.
   * A RegExp can also be provided. If stripeUri is true, the first capturing
   * parenthesis will be used. If none present the whole match will be used.
   */
  uris?: (string | RegExp)[];
  /**
   * Protocol to use on the upstream. The default is http.
   */
  protocol?: "http:" | "https:";
  /**
   * Timeout when the gateway give up on the upstream. There is a default
   * of 30 seconds.
   */
  timeout?: number;
  /**
   * All middleware to apply on the client request or response.
   */
  requestMiddlewares?: RequestMiddleware[];
  /**
   * All middleware to apply on the upstream response.
   */
  responseMiddlewares?: ResponseMiddleware[];
  /**
   * Preserve the original host from the client. The default is false.
   */
  preserveHost?: boolean;
  /**
   * Remove the matched path from the rest of the URI. E.g.
   * If the matcher path is /admin/ and the incoming request is /admin/user/123
   * the uri used on the upstream will become /user/123. As leading slash is enforced.
   * The default is false.
   */
  stripeUri?: boolean;
}

Performance and scalability

Load test with artillery, core usage ~15%

config:
  target: "http://localhost:3000"
  phases:
    - duration: 60
      arrivalRate: 100
scenarios:
  - flow:
      - get:
          url: "/test"
          headers:
            host: loadtest

Backend with 0ms latency

Summary report @ 10:16:08(+0200) 2021-06-24
  Scenarios launched:  6000
  Scenarios completed: 6000
  Requests completed:  6000
  Mean response/sec: 99.16
  Response time (msec):
    min: 0
    max: 52
    median: 1
    p95: 2
    p99: 3
  Scenario counts:
    0: 6000 (100%)
  Codes:
    200: 6000

Backend with 200ms latency

Summary report @ 10:09:00(+0200) 2021-06-24
  Scenarios launched:  6000
  Scenarios completed: 6000
  Requests completed:  6000
  Mean response/sec: 99.16
  Response time (msec):
    min: 200
    max: 256
    median: 202
    p95: 203
    p99: 225
  Scenario counts:
    0: 6000 (100%)
  Codes:
    200: 6000