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

dino-express

v2.0.16

Published

DinO enabled REST framework based on express

Downloads

42

Readme

DinO Express

:warning: Starting from release 1.0.5 dino-express provide dino-serverless features as well, as a result dino-serverless will not receive any more updates. If you are using dino-express < 1.0.5 please migrate to dino-express >= 1.0.5 following the information provided here to update the your entrypoint.

DinO Express's aim is to create a configuration first framework for exposing web APIs. The basic idea os that the first step of development starts with defining your Swagger/OpenAPI definition and provide it to DinO Express which will map your API and connect directly your code using the standard operationId defined for each API, this allow you to focus on your business requirements and the aspects that matters for your application leaving the boilerplate to DinO Express.

In order to be able to connect your Swagger/OpenAPI definition with your code seamlessly DinO Express define the concept of Interface, an interface is a Component on DinO world which responsibility is to accept the input from the users and propagate, after the required checks are performed, it to your services.

An example of how DinE Express works is provided on the examples/json folder, you can run it using the following command:

DINO_CONTEXT_ROOT=examples/json DINO_CONFIG_PATH=examples/json/config.json node examples/json/main.js

DinO Express integrate with Swagger UI, this allow you to easily test your APIs and provide a clear interface for documentation, the Swagger UI will ba accessible at http://localhost:3030/api-docs or in general http[s]://hostname[:port]/api-docs.

Configuration

API configuration

API configuration is primarily done via OpenAPI 3.0 definition. Some aspects are configured via a configuration file.

Service Configuration

Service configuration can be defined via DINO_CONFIG_PATH environment variable, configuration parameters are described below:

{
  "application": {
    "name": "The name of the application, will be used as identifier for logging, events and any other identification based activities, if not provided defaults to OpenAPI info.title field"
  },
  "dino": {
    "active": {
      "profiles": "activate one or more runtime profiles, if more than one needs to be activated, provide a comma separated list of active profiles"
    },
    "api": {
      "validation": {
        "enabled": "true|false flag enable or disable api request/response validation",
        "configuration": "an object providing express-openapi-validator validation options"
      },
      "handler": {
        "type": "defines how parameters are provided to the method handling the request, valid options are proxy and request. if set to proxy destructured properties will be provided"
      }
    },
    "cloud": {
      "integration": "define the integration type when deployed as a lambda integrating with AWS API Gateway, allowed values are method default, or proxy",
      "provider": "The cloud provider, supported are aws and google",
      "service": "The cloud service used to run the application, supported value are lambda for aws and function for google, running as a standalone application does not require this configuration"
    },
    "environment": "define the environment the application is running on",
    "openapi": {
      "descriptor": {
        "path": "The routing configuration path",
        "provider": "The provider for the openapi configuration only supported is filesystem"
      }
    },
    "security": {
      "enabled": "true|false flag enables security aspects, this feature is under active implementation, additional features will come",
      "https": {
        "enabled": "a flag indicating if https should be configured",
        "config": "HTTPS configuration object accepts all configuration provided by https module as defined at https://nodejs.org/api/https.html#httpscreateserveroptions-requestlistener"
      }
    },
    "observability": {
      "enabled": "true|false enable or disable application observability, application lifecycle events",
      "eventEmitter": "the name of the event emitter to use, defaults to logEventEmitter, the name will be used to resolve the instance from the application context meaning that a configuration class should be created that makes the eventEmitter available",
      "batchSize": "the number of application event to batch before emitting, defaults to 1"
    },
    "server": {
      "docs": "the path for the swagger-ui, defaults to /api-docs",
      "expose": "the type of apis exposed by the application valid values are api, event, mixed",
      "monitoring": {
        "enabled": "true|false flag enables application monitoring, when enabled a new /monit endpoint is automatically exposed",
        "co2": "true|false flag enables co2 emission monitoring"
      },
      "payloadSize": "the maximum size for the payload, default to 100kb",
      "path": "the base path for the server defaults to /",
      "port": "the port the server will be exposed, defaults to 3030",
      "request": {
        "forceBase64Decode": {
          "enabled": "true|false flag enables force decode the first level of the incoming request if encoded as base64, decompress and parse from JSON if needed. Assumes that the string is compressed and after base64 encoded",
          "paths": "array of paths to decode"
        }
      },
      "response": {
        "asBase64": "true|false flag enables encoding response as base64"
      },
      "type": "The type of exposed server, valid options are standalone and embedded, deprecated options are express and serverless"
    }
  }
}

Monitoring

If enabled an additional endpoint /monitor is exposed that provides useful information about the application status.

Exposed information are:

  1. UP/DOWN status
  2. Per-API cache - when enabled - information
  3. CO2eq runtime emissions if enabled via the dino.server.monitoring.co2 configuration. CO2eq monitoring is executed using the CO2.js library provided by The Green Web Foundation

Monitoring is enabled by default and can be controlled enabled/disabled using the dino.server.monitoring.enabled configuration.

Example

{
  "dino": {
    "monitoring": {
      "enabled": true|false,
      "c02": true|false
    }
  }
}

Caching

Dino-express uses apicache-plus module to provide caching functionalities. Caching is enabled adding the cache directive as part of the API definition, available configuration aspects are:

| Parameter | Description | Default | | ---------------- | ------------------------------------------------------------------------------------------------------------- | ---------- | | ttl | The TTL of the cache for this API | 30 minutes | | debug | Enable debug statements for on console | false | | trackPerformance | Enable performance tracking for the API cache, performance monitoring can be observed via /monitor endpoint | true | | isBypassable | Allows to bypass cache by requesting with Cache-Control: no-store header | true |

Example

---
paths:
  /uuid:
    get:
      summary: Get a UUID
      operationId: getUUID
      tags:
        - uuid
      parameters: {}
      x-dino-express-cache:
        ttl: 30 Seconds
        debug: false
        trackPerformance: true
        isBypassable: true
      responses:
        '200':
          description: An object containing a UUID
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UUID'
        default:
          description: unexpected error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

Access control policies

Dino-express proposes out ot the box a quota and rate limiting policies that allows to manage access to the APIs, policies can be configured via OpenAPIs, using x-dino-express-policies, as following:

  • Rate Limit, spike arrest policy helps protecting the backend against spikes of traffic or Denial of Service attacks, it should not be used to control or limit the number of requests that are received by the backend in a specific time window, for this a quota policy should be used. Configuration parameters for the policy are:

    • interval, the interval at which the spike arrest should be reset expressed in ms
    • allow, the number of requests that are allowed inside the window interval

    When the policy is triggered and the requests is denied a 429 HTTP response code is returned with message "Too Many Requests".

    The rate window is calculated as (interval/1000)/allow this allows to segregate requests in spike windows of a specific duration, i.e if interval is set to 60000 (one minute) and allow is set to 30 (30 allow request each minute) the spike window duration will be 2 seconds meaning that only one request is allowed to the backend every 2 seconds.

    The policy will count requests based on the client IP Address.

  • Quota, quota policy helps limit the amount of requests that a client can make to the backend over a specific amount of time, it should not be used to protect the backend against spikes. Configuration parameters for the policy are:

    • resetInterval, the interval at which the quotas should be reset expressed in ms
    • window, the time window the quota should be defined for expressed in ms
    • allow, the number of requests that are allowed inside the window interval

When the policy is triggered and the requests is denied a 429 HTTP response code is returned with message "Quota Exceeded". The policy will count requests based on the client IP Address.

Cors

Dino Express allows to configure Cors on a per-api bases using the x-dino-express-cors object, the configuration is provided as described at https://expressjs.com/en/resources/middleware/cors.html.

If the x-dino-express-cors object is not defined CORS will not be enabled, instead will be explicitly disabled using the configuration { origin: false } as described here.

Example

---
paths:
  /uuid:
    get:
      summary: Get a UUID
      operationId: getUUID
      tags:
        - uuid
      parameters: {}
      x-dino-express-cors:
        origin: "*",
        methods: "GET,HEAD,PUT,PATCH,POST,DELETE",
        preflightContinue: false,
        optionsSuccessStatus: 204
      x-dino-express-policies:
        rate-limit:
          name: rateLimitPolicy
          configuration:
            allow: 1
            interval: 1000
        quota:
          name: quotaPolicy
          configuration:
            allow: 2
            window: 10000
            resetInterval: 30000
      responses:
        '200':
          description: An object containing a UUID
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UUID'
        default:
          description: unexpected error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

Service Configuration

{
  "application": {
    "name": "The name of the application, will be used as identifier for logging, events and any other identification based activities, if not provided defaults to OpenAPI info.title field"
  },
  "dino": {
    "active": {
      "profiles": "activate one or more runtime profiles, if more than one needs to be activated, provide a comma separated list of active profiles"
    },
    "api": {
      "validation": {
        "enabled": "true|false flag enable or disable api request/response validation",
        "configuration": "an object providing express-openapi-validator validation options"
      },
      "handler": {
        "type": "defines how parameters are provided to the method handling the request, valid options are proxy and request. if set to proxy destructured properties will be provided"
      }
    },
    "cloud": {
      "integration": "define the integration type when deployed as a lambda integrating with AWS API Gateway, allowed values are method default, or proxy",
      "provider": "The cloud provider, supported are aws and google",
      "service": "The cloud service used to run the application, supported value are lambda for aws and function for google, running as a standalone application does not require this configuration"
    },
    "environment": "define the environment the application is running on",
    "openapi": {
      "descriptor": {
        "path": "The routing configuration path",
        "provider": "The provider for the openapi configuration only supported is filesystem"
      }
    },
    "security": {
      "enabled": "true|false flag enables security aspects, this feature is under active implementation, additional features will come",
      "https": {
        "enabled": "a flag indicating if https should be configured",
        "config": "HTTPS configuration object accepts all configuration provided by https module as defined at https://nodejs.org/api/https.html#httpscreateserveroptions-requestlistener"
      }
    },
    "observability": {
      "enabled": "true|false enable or disable application observability, application lifecycle events",
      "eventEmitter": "the name of the event emitter to use, defaults to logEventEmitter, the name will be used to resolve the instance from the application context meaning that a configuration class should be created that makes the eventEmitter available",
      "batchSize": "the number of application event to batch before emitting, defaults to 1"
    },
    "server": {
      "docs": "the path for the swagger-ui, defaults to /api-docs",
      "expose": "the type of apis exposed by the application valid values are api, event, mixed",
      "monitoring": {
        "enabled": "true|false flag enables application monitoring, when enabled a new /monit endpoint is automatically exposed",
        "co2": "true|false flag enables co2 emission monitoring"
      },
      "payloadSize": "the maximum size for the payload, default to 100kb",
      "path": "the base path for the server defaults to /",
      "port": "the port the server will be exposed, defaults to 3030",
      "request": {
        "forceBase64Decode": {
          "enabled": "true|false flag enables force decode the first level of the incoming request if encoded as base64",
          "paths": "array of paths to decode"
        }
      },
      "response": {
        "asBase64": "true|false flag enables encoding response as base64"
      },
      "type": "The type of exposed server, valid options are standalone and embedded, deprecated options are express and serverless"
    }
  }
}

Roadmap

  • Security validation based on Swagger/OpenAPI definition
  • Better documentation