death-adder
TypeScript icon, indicating that this package has built-in type declarations

0.5.1 • Public • Published

Death Adder

A web application library for Node.js

Goals

Death Adder aims to be a a simple and lightweight library for building web applications, specifically RESTful APIs, with a simple and readable interface. Death Adder favors minimizing dependencies and keeping the feature set narrow.

Installation

To add Death Adder to your project, simply install it

with npm:

npm install death-adder

or yarn:

yarn add death-adder

Usage

The use of Death Adder consists of three primary components. A Server is responsible for listening to network requests and dispatching them to a Router. The Router is responsible for associating the path of the request to a specific web resource. An Endpoint handles responding to network requests with a specific resource.

In code, the pattern looks like the following:

// Using ES6 Imports
import { Server, Router, Endpoint } from 'death-adder';

// Using require
const { Server, Router, Endpoint } = require('death-adder');


// Create the definitions for your Endpoints
class SquirtleEndpoint extends Endpoint {
  get(request, response) {
    response.send('Squirtle');
  }
}

class CharmanderEndpoint extends Endpoint {
  get(request, response) {
    const charmander = { name: 'Charmander', type: 'fire' };
    response.json(charmander);
  }
}

const router = new Router();
// Added with an endpoint definition
router.addHandler('/squirtle', SquirtleEndpoint);

// Although it is not as recommended because of the ability
// to store state in an instance and cause side effects, it
// is also possible to add an instance of an Endpoint
router.addHandler('/charmander', new CharmanderEndpoint());

const server = new Server(router);

server.listen(3000);

/**
 * Alternatively one could do:
 * 
 * const server = new Server(router, 3000);
 * server.listen();
 * 
 * or:
 * 
 * const server = new Server();
 * server.setRouter(router);
 * server.listen(3000);
 * 
 */

The use of middleware allows the selective administration of certain actions based on the path or requested resource. In order to use Death Adder middlewares, add a middleware function to an Endpoint or instance of Router. Importantly, the return value of a middleware determines if the application will continue attempting to handle the request. A return value of false immediately ends the execution of any further request handling. It is up to the request terminating middleware to send the response to the client. Middleware can also be asynchronous, and continued execution will await the resolution of a Promise .

import { Server, Router, Endpoint } from 'death-adder';

class EndpointWithMiddleware extends Endpoint {
  constructor() {
    // A naive middleware for validating the request is from
    // localhost
    this.middleware.push(
      (request, response) => {
        if (request.ip !== '127.0.0.1') {
          // Return a 401 and terminate execution
          response.unauthorized();
          return false;
        }
        return true;
      }
    );
  }
  get(request, response) {
    response.send(
      'Request to the Endpoint With Middleware was allowed'
    );
  }
}

class TypicalEndpoint extends Endpoint {
  get(request, response) {
    response.send('Request to the Typical Endpoint was allowed');
  }
}

const apiRouter = new Router();
router.addMiddleware(
  (request, response) => {
    if (!request.headers['authorization']) {
      response.unauthorized();
      return false;
    }
    return true;
  }
)
apiRouter.addHandler('/third', EndpointWithMiddleware);
apiRouter.addHandler('/second', TypicalEndpoint);

const baseRouter = new Router();
baseRouter.addHandler('/api', apiRouter);
baseRouter.addHandler('/first', TypicalEndpoint);

const server = new Server(baseRouter, 3000);

server.listen();

In this example, requests to http://localhost:3000/first will resolve without any additional requirements, while requests to http://localhost:3000/api/second will require the Authorization header to be set. Furthermore, requests to http://localhost:3000/api/third will require the Authorization header to be set as well as be from localhost. Middleware functions can return a boolean, return a Promise which resolves to a boolean, or expect a callback function to provide a boolean to. The following are all valid examples of Death Adder middlewares:

const syncMiddleware = (request, response) => {
  return true;
}

const promiseMiddleware = (request, response) => {
  return new Promise((resolve) => {
    setTimeout(resolve, 1000);
  });
}

const callbackMiddleware = (request, response, callback) => {
  setTimeout(() => callback(true), 1000);
}

In order to handle the separate HTTP methods, the Endpoint class has five separate functions representing the HTTP methods which can be overriden by child classes. These are:

get();
post();
put();
delete();
patch();

By default, any of these methods which are not overriden will return a 404 (Not Found) error.

Similarly, the Response class provides a number of built in methods for sending common response types to clients. These methods are:

send(); // 200
json(); // 200
badRequest(); // 400
unauthorized(); // 401
notFound(); // 404
error(); // 500

Package Sidebar

Install

npm i death-adder

Weekly Downloads

2

Version

0.5.1

License

MIT

Unpacked Size

37.9 kB

Total Files

36

Last publish

Collaborators

  • snoretrain