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

@wwu-restek/rt-api-server

v1.2.20

Published

Server architecture for standard, Express based Node servers.

Downloads

65

Readme

ResTek API Server Framework

This is a Node server framework designed with the needs of ResTek in mind. It allows for cleaner namespacing of routes and structuring servers in a way that's scalable.

Setup

This package isn't available on npm (yet), so we'll need to install it to a project via git+ssh.

npm install @wwu-restek/rt-api-server

Documentation

If you want to look at more detailed documentation, run the following:

cd rt-api-server
npm run build_docs

This will create a directory called docs. Open the index.html file in a web browser for the documentation.

Usage

HTTP Server

To setup a basic HTTP server, do the following:

const { RTServer } = require('@wwu-restek/rt-api-server').Server;
const { Route, RouteContainer } = require('@wwu-restek/rt-api-server').Routing;

const server = new RTServer(5000);
const rc = new RouteContainer('test');

rc.addRoute(new Route('GET', '/hello', (req, res) => {
  res.send('Hello, world!');
}));

server.loadRoutes(rc).start();

This creates a server at http://localhost:5000 with a single endpoint http://localhost:5000/test/hello that returns the text Hello, world!.

Routing

There are many ways to add/remove routes at runtime.

We can add or remove a Route at runtime to a RouteContainer/RouteModule:

const { Route, RouteContainer } = require('@wwu-restek/rt-api-server').Routing;

const rc = new RouteContainer('/');
const route = new Route('GET', 'test', (req, res) => res.send('Hello, world!'));

// Add route
rc.addRoute(route);

// Remove route
rc.removeRoute(route);

In order to remove a route, you MUST save a reference to the route.

We can also add/remove RouteContainers to other RouteContainers or RouteModules:

const childRC = new RouteContainer('child');
const parentRC = new RouteContainer('parent');

// Merge the child RouteContainer
parentRC.addRouteContainer(childRC);

// Remove the child RouteContainer
parentRC.removeRouteContainer(childRC);

Similar to removing Routes, you MUST save a reference to the child RouteContainer in order to remove it.

Route Modules

We can wrap up an entire API server's routing tree and export that as a plugin that other microservices/APIs can use.

const { RouteModule } = require('@wwu-restek/rt-api-server').Routing;
const rc = require('./someRouteContainer'); // This is a RouteContainer object

const rm = new RouteModule('/');
rm.addRouteContainer(rc);

module.exports = rm;

We can now use this RouteModule in other APIs/microservices as a pluggable routing module.

Route modules can also quickly create their own small RTServers that are great for development or testing.

const { Route, RouteModule } = require('@wwu-restek/rt-api-server').Routing;

const route = new Route('GET', '/test', (req, res) => res.send('Hello, world!'));

const rm = new RouteModule('/');
rm.addRoute(route);

rm.start(); // Picks a port that is available for use to serve /test

Authentication

@wwu-restek/rt-api-server comes bundled with configuration options and middleware to make CAS authentication easy to use. It uses the @wwu-restek/simple-cas module to accomplish everything related to CAS.

At the server level

To configure an RTServer object to use CAS globally:

const { RTServer } = require('@wwu-restek/rt-api-server').Server;

const server = new RTServer(80, { 
  session: { /* session configuration */},
  auth: { baseHost: <some base>, serviceUrl: <CAS redirect URL> },
});

auth can be set to a boolean to use the default behavior or can be an object with two optional parameters. The default behavior is to redirect the client to CAS and have them return to the exact same route that they requested originally.

baseHost is an optional paramater for the hostname for CAS to redirect to after authentication. This is useful if you have a server running at localhost:8000 since req.hostname doesn't preserve the port number in the hostname.

serviceUrl is a full URL for CAS to redirect to after authentication. This is optional in case you need users to redirect back to a front-end server after being redirected from the backend.

NOTE - You need to configure sessions in order to use CAS authentication. This is because the server needs somewhere to store CAS authentication information. The middleware that is used will throw an error if there is no session.

As middleware

There is also middleware that can be used just to protect individual routes or route containers:

const { RouteContainer } = require('@wwu-restek/rt-api-server').Routing;
const { auth } = require('@wwu-restek/rt-api-server').Auth;

const rc = new RouteContainer('/', auth({ baseHost: 'some base', serviceUrl: 'some service url' }));

auth takes either true or a configuration object. The behavior is the same as the server config.

Middleware

We can add middleware a couple of different ways.

We can add middleware to an RTServer, RouteContainer, or Route at instantiation:

// Add middleware to all routes of a server
const server = new RTServer(5000, { middleware: [(req, res, next) => { console.log('Hello, world!'); next(); }] });

// Add middleware to all routes within a RouteContainer
const rc = new RouteContainer('test', 
                              (req, res, next) => { console.log("I'm middleware 1"); next(); },
                              (req, res, next) => { console.log("I'm middleware 2"); next(); },
);

// Add middleware to a single route
const route = new Route('GET', 
                        '/foo',
                        (req, res, next) => { console.log("I'm route-specific middleware"); next(); },
                        (req, res) => { res.send('foo'); },
);

We can also add middleware to any of these objects after instantiation:

server.addMiddleware(middleware1, middleware2);
rc.addMiddleware(middleware3);
route.addMiddleware(middleware4, middleware5, middleware6);

Error Handling

At any point, you can throw an RTError to send a client an RFC 7807 compliant error message:

const { RTError } = require('rt-api-server').ErrorHandling;

const route = new Route('GET', '/error', (req, res) => { 
  throw new RTError('This is a test error message',      // Description of error
                    400,                                 // HTTP status code
                    { custom: 'Custom error message' }); // (Optional) More details about error for client
});

Socket.io

We can also utilize socket.io for duplex communication:

// server.js
const server = new RTServer(5000, { socket: true });
server.addSocketListener('connection', () => { console.log('Received connection'); });
server.start();
// client.js
const io = require('socket.io-client');
const client = io('http://localhost');
client.on('connect', () => { console.log('Connected'); };