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

simple-wsgi

v1.1.0

Published

Creates a webserver for development or production. Bring your own application!

Downloads

13

Readme

Simple WSGI server for NodeJS

WSGI stands for Web Server Gateway Interface. It's a common pattern in Python web development, essentially you decouple the code that starts the web server from the application code that actually handles the incoming requests (and everything else your application does). That way you can easily deploy the same application tailored to different environments (providing that environment has a WGSI server available for it).

Unfortunately the NodeJS world has yet to catch up with this pattern. But the good news is that it's not hard to implement - and the better news is that it's not hard to modify existing projects to use this pattern!

Todo: Add yargs for port etc

// app.js

module.exports = function main(req, res) {
	res.end(`This is my WSGI application!`);
}
// server.js

module.exports = function startServer(application) {
	http.createServer(application, ()=>console.log('This is my WSGI server!'));
}

// Optional: Allow command line usage
if(require.main === module) {
	startServer(require(process.argv[2]));
}

Wow, two really simple interfaces! How do they combine?

// This is how they work together in a script!
const startServer = require('./server.js');
const main = require('./app.js');

startServer(main);
# This is how they work together on the command line!

node server.js ./app.js

This is the de-facto WSGI API for NodeJS (although it's not usually called that by name). It comes from Node's http.createServer function. The vast majority of NodeJS web applications at some point create a callback that is passed to this function. If we make all of our web server applications compatible with this function anyway, why not factor out the server setup to a separate library?

Maybe a library such as this one.

How to use this library

This library provides WSGI servers for two environments: Development and "Production". Actually the production server is quite naïve, it just starts up a cluster and runs the application on each worker.

First you need to make sure you are exporting a function that accepts the Request and Response arguments, as in the example.

Now you can start your server:

// Import the wsgi server
const startServer = require('simple-wsgi');

// Import the wsgi application
const app = require('./application.js');

// We automatically detect wherther the environment is dev or production
// by checking the NODE_ENV env variable
const port = 3000;
startServer(app, port);

The port argument is optional, it defaults to process.env.PORT if present, otherwise to 8080 on development and 80 on production.

Alternatively we can be explicit about which environment we want to use:

startServer.production(app);
startServer.development(app);

More fun things you can do

Once you have a lot of applications using this interface you can start to do some interesting things. Like having multiple distinct applications under different domain names listening on the same port. Take a look at this:

const applicationA = require('app-a');
const applicationB = require('app-b')({ example: 'Maybe this app takes some config' });

module.exports = function multiSite(req, res){
	switch(req.getHeader('host')) {
		case 'pokemon-red-cheat-codes.example':
			return applicationA(req, res);
		case 'family-recipes.example.com':
			return applicationB(req, res);
		default:
			res.end(`I'm not sure what you're looking for. We only have cheat codes and recipes.`);
			return;
	}
}

if(require.main === module) {
	require('simple-wsgi')(multiSite);
}

Isn't that better than writing another Apache/Nginx config? Well I think it is.

Questions

What about config options?

It's true, this pattern doesn't have the full capabilities of the Python WSGI specification. But I think for people to start adopting the WSGI pattern it needs to be familiar and easy to use. That said, there's already a de-facto standard of using environment variables for configuration. Try that! Once multiple WSGI servers start becoming available perhaps we can come to a consensus on how to handle config and other extras. Until then......... sorry!

I think I have an idea that would make this better?

Wow, I'd love to hear it! We are stronger when we work together and share our ideas! Please let me know your thoughts in an issue, or contact me by my contact details on mrkiddle.co.uk

You know someone else has already done the same thing?

What, exactly the same? I didn't know that! If I knew that I wouldn't have done it myself. Please let me know who!