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

rest-controllers

v0.0.5

Published

Minimalistic REST controllers framework for ExpressJS

Downloads

4

Readme

rest-controllers

The framework is to provide minimal REST controllers configuration for ExpressJS server.

usage

Create directory to place all controllers (default is [project root]/controllers).

The controllers should follow simple convention:

  • controller file name without extension will be the controller name

If controller has method

  • read: then HTTP GET requests to [controller name] and [controller name]/id will be forwarded to this method
  • write: then HTTP PUT requests to [controller name] will be forwarded to this method
  • create: then HTTP POST requests to [controller name] will be forwarded to this method
  • remove: then HTTP DELETE requests to [controller name] will be forwarded to this method
  • started with underscore: such method will be ignored in routing
  • for any method started with word 'read', 'write', 'create' and 'remove' and followed by capital letter the same convention will be used but the URL will be like [controller name]/[method name without first word] and first capital letter will be changed to lowercase, for example, createDatabase method of controller manage.js will handle POST requests to manage/database
  • route: this method will be used during initialization to define custom rules. The method signature will be: route(router) where router object has a set of methods to define custom rules (see below); all routes definitions can accept
  • all other method names will be considered as handling GET requests only

Each read method will get the following arguments:

method(id, req, res);

where

  • req, res are appropriate ExpressJS request and response objects

Each write/create/remove method will get the following arguments:

method(body, req, res);

where

  • body is the HTTP request body, parsed as JavaScript object if it is JSON
  • req, res are appropriate ExpressJS request and response objects

Each GET method (last entry from the list above) will get no arguments.

Each method specified through route call will be defined as

method(arg1, arg2, ... [, body], req, res);

where

  • arg1, arg2, ... are regular exception groups if route defined through regular expression
  • body (doesn't applicable for GET requests) is the HTTP request body, parsed as JavaScript object if it is JSON
  • req, res are appropriate ExpressJS request and response objects

In case method return value contains:

  • object - it will be returned as JSON response.
  • string - the handler will try to treat it as path to resource file path and if it exists it will return appropriate file as response; otherwise it will return string as plain text response
  • any other value - no additional response will be generated; the method should generate response by itself using 'res' object

Promises also accepted as return values. In this case, the promise resolve will be checked against the rules above.

router API

Router object supports the following calls:

  • route(method, path, callback)
  • get(path, callback)
  • post(path, callback)
  • put(path, callback)
  • remove(path, callback)

Where only first method does actual work and next four methods are shortcuts for appropriate HTTP methods.

path contains rule to check URL after "controller/" part. It can contain string or regular expression. If it is string, it will be joined with controller name and compared to the actual URL. For example, 'method' will be transferred to 'controller/method'. If it is regular expression, it will be used to compare the same URL part going after "controller/". If the expression has groups, they will be passed as arguments to the callback. callback contains function to be called. The function will be called with 'this' set to the controller instance.

initialization and options

var express = require('express');
var app = express();
var restControllers = require('rest-controllers');
var options = {
    ...
};
restControllers(app, options);

The following options supported:

  • controllers path to directory where all controllers reside, default 'controllers'; or object with key/value pairs set to each controller name and instance respectively, in case you want to load controller instances manually
  • error error handler function, accepts one parameter with error contents; default undefined
  • noEmptyRead set to true to not to create default read handlers without '/id' in URL; default false
  • resources path which will be used as resources root; default project root
  • debug function to output debug messages
  • route regular expression to handle routes; should have one group which will be used as matched url for further parsing; for example, if you want to handle only calls to 'api/controller/method' instead of 'controller/method', you can set it to /^api/(.+)$/; default will use full url
  • notFoundHandler function which will handle requests where no match is found; uses signature handler(req, res); default sends 404 response

examples

simple controller

controllers/test.js

module.exports = {
    read: function(id) {
        return 'abc';
    },
    write: function(body) {
        return {
            status: 'success'
        };
    }
};

In this case only these three requests will be handled:

  • HTTP GET /test
  • HTTP GET /test/id
  • HTTP PUT /test

First two requests will return 'text/plain' response containing 'abc'; Last request will return JSON object containing {"status":"success"}

controller with routing and complex functions

controllers/authenticate.js


var database = ...;

module.exports = {
    route: function(router) {
        router.put(/^login\/(\w+)$/, this._handleLogin);
    },

    _database: database,

    _handleLogin: function(site, body) {
        // req and res are omitted as they are not used
        var user = this._database.getUser(site, body.username);
        return user;
    },

    createUser: function(body, req, res) {
        res.set('authId', 100);
        return this._database.createUser(body.userName);
    }
};

will create these two rules:

  • HTTP PUT /authenticate/login/sitename where 'sitename' can be any text value with no spaces; will be handled by _handleLogin
  • HTTP POST /authenticate/user will be handled by createUser function