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

route-harness

v2.1.6

Published

Simple route harness for Express.

Downloads

17

Readme

route-harness

CircleCI Language grade: JavaScript npm npm type definitions

Simple express harness

  • wrap all routes in a common error handler
  • define your routes using es6 classes

 npm install --save route-harness

Example

Just pass the express app to the harness, and start defining your route classes.


const express = require('express');
const RouteHarness = require('route-harness');

const app = express();

const harness = new RouteHarness(app, { /* options */ });

harness.use('/users', require('./routes/Users.js'));

In your ./routes/Users.js file:


module.exports = class UsersRoutes {

  constructor(dependencies)
  {
    const router = dependencies.router;

    router.get('/', this.getUsers);
    router.get('/:id', this.getById);
  }

  async getUsers(req, res)
  {
    let users;

    // ...

    return users;
  }

  async getById(req)
  {
    const id = req.params.id;
    let user;

    // ...

    return user;
  }

};

For more examples see the examples directory.

Return Values

If you return a value from your route class method, the value will be sent with the res.send method. Otherwise if a falsy value is returned (or there is no return value) you are expected to handle the response in the class method yourself.

If an error is thrown within a route class method, it will be caught and forwarded to the next() callback provided by express if you haven't provided the customWrapper option.

Class Parameters

You will by default get an object passed to your route class constructors containing injected dependencies as properties. There will be a router property provided by route-harness. The router property allows you to define your sub-routes with the get, post, put, delete methods.

You can also customize what your constructors get injected with via the factory option. The factory function will receive the route class as well as any injected dependencies as its parameters. The factory function expects the newly created class instance as its return value. Note: You can use the injected router property for passing into your route classes here or use the harness dependency for fetching the router from within the class.

Logging

There is nothing logged to the console by default. You can provide the customWrapper option to handle logging however you please.

Advanced Options:

All options are optional and calling new Harness(app) using 1 param is supported.


const opts = {

  // 1) factory: custom route class instantiation
  factory: (T, deps) => new T(deps),

  // 2) inject: dependencies passed to class constructors
  inject: { db, cheerio /*, ...etc. */ },

  // 3) customWrapper: override default wrapper with a custom one
  customWrapper: (handler, info, injectedProps) => {

    const route = `${info.method} '${info.fullPath}'`;
    const name = `${info.routeClass}.${info.handler}`;

    console.log(`[harness] mapping: ${route} to ${name}`);

    return async (req, res, next) => {

      console.log(`[harness] route hit: ${route} ${name}`);

      // call the handler here and process errors and return values
      try {
        const result = await handler(req, res);
        if (result) {
          res.send(result);
        }
      }
      catch (error) {
        console.error(`[harness] error in route ${route}: `, error);
        next(error);
      }

    };
  }
};
  • factory

    Provide a custom factory function if you want control over how your route classes are initialized. It takes a route class and injectables object as params and should return a new instance of that class. There will also be a restHarness property as a property of the injectables param for seting up routes from within the route class constructors.

  • inject

    Inject option allows you to provide dependencies that will be passed as properties of the first parameter of the class constructor of your route files. If you are providing the custom factory option, these injected dependencies will be provided as the second argument to your factory function.

  • customWrapper

    Provide the customWrapper option to customize your centralized route wrapper. This option is a high order function that takes in a RouteClass method (route handler), an info object, and injected dependencies as its parameters, and returns an express looking function. The customWrapper's returned function should invoke the RouteClass method (the route handler) in its body to delegate the incoming request to, it should also handle any errors thrown by the route handler method. The info parameter object will contain properties describing the route being hit and the class and method name being used.

API

RouteHarness

new RouteHarness(app, options)

RouteHarness#use(routePath, [middleWare], RouteClass)

RouteHarness#asDependency()

Router

Router#get(subPath, [middleWare], handlerMethod)

Router#put(subPath, [middleWare], handlerMethod)

Router#post(subPath, [middleWare], handlerMethod)

Router#delete(subPath, [middleWare], handlerMethod)

HarnessDependency

HarnessDependency#getRouterForClass(className)

HarnessDependency#getDeps([className])