Skip to content

rstackjs/connect-next

Repository files navigation

connect logo

NPM Version NPM Downloads

connect-next

connect-next is an actively maintained fork of Connect.

Connect is an extensible HTTP server framework for node using "plugins" known as middleware.

Changes

  • Requires Node.js ^20.19.0 || >=22.12.0
  • Rewrites with TypeScript
  • Publishes as native ESM via "type": "module"
  • Exposes a named connect export
  • Removes utils-merge dependency
  • Upgrades debug to v4
  • Upgrades finalhandler to v2

Example

import { connect } from 'connect-next';
import { createServer } from 'node:http';
import compression from 'compression';
import cookieSession from 'cookie-session';
import bodyParser from 'body-parser';

const app = connect();

// gzip/deflate outgoing responses
app.use(compression());

// store session state in browser cookie
app.use(
  cookieSession({
    keys: ['secret1', 'secret2'],
  }),
);

// parse urlencoded request bodies into req.body
app.use(bodyParser.urlencoded({ extended: false }));

// respond to all requests
app.use((req, res) => {
  res.end('Hello from Connect!\n');
});

// create an HTTP server and listen on port 3000
createServer(app).listen(3000);

Getting Started

Connect is a simple framework to glue together various "middleware" to handle requests.

Install Connect

$ npm install connect-next

Migrate from connect

If you are migrating from connect, remove the previous packages and install connect-next:

$ npm remove connect @types/connect
$ npm install connect-next

connect-next ships its own TypeScript types, so @types/connect is no longer needed.

The package also exposes a named connect export instead of a default import:

-import connect from 'connect';
+import { connect } from 'connect-next';

Create an app

The main component is a Connect "app". This will store all the middleware added and is, itself, a function.

import { connect } from 'connect-next';

const app = connect();

Use middleware

The core of Connect is "using" middleware. Middleware are added as a "stack" where incoming requests will execute each middleware one-by-one until a middleware does not call next() within it.

app.use(function middleware1(req, res, next) {
  // middleware 1
  next();
});
app.use(function middleware2(req, res, next) {
  // middleware 2
  next();
});

Mount middleware

The .use() method also takes an optional path string that is matched against the beginning of the incoming request URL. This allows for basic routing.

app.use('/foo', function fooMiddleware(req, res, next) {
  // req.url starts with "/foo"
  next();
});
app.use('/bar', function barMiddleware(req, res, next) {
  // req.url starts with "/bar"
  next();
});

Error middleware

There are special cases of "error-handling" middleware. There are middleware where the function takes exactly 4 arguments. When a middleware passes an error to next, the app will proceed to look for the error middleware that was declared after that middleware and invoke it, skipping any error middleware above that middleware and any non-error middleware below.

// regular middleware
app.use((req, res, next) => {
  // something failed
  next(new Error('boom!'));
});

// error middleware for errors that occurred in middleware
// declared before this
app.use(function onError(err, req, res, next) {
  // an error occurred!
});

Create a server from the app

The last step is to actually use the Connect app in a server. The .listen() method is a convenience to start a HTTP server (and is identical to the http.Server's listen method in the version of Node.js you are running).

const server = app.listen(port);

The app itself is really just a function with three arguments, so it can also be handed to .createServer() in Node.js.

import { createServer } from 'node:http';

const server = createServer(app);

Middleware

These middleware and libraries are officially supported by the Connect/Express team:

Most of these are exact ports of their Connect 2.x equivalents. The primary exception is cookie-session.

Some middleware previously included with Connect are no longer supported by the Connect/Express team, are replaced by an alternative module, or should be superseded by a better module. Use one of these alternatives instead:

Checkout http-framework for many other compatible middleware!

API

The Connect API is very minimalist, enough to create an app and add a chain of middleware.

When the connect-next module is imported, the named connect export is a function that will construct a new app when called.

// import module
import { connect } from 'connect-next';

// create app
const app = connect();

app(req, res[, next])

The app itself is a function. This is just an alias to app.handle.

app.handle(req, res[, out])

Calling the function will run the middleware stack against the given Node.js http request (req) and response (res) objects. An optional function out can be provided that will be called if the request (or error) was not handled by the middleware stack.

app.listen([...])

Start the app listening for requests. This method will internally create a Node.js HTTP server and call .listen() on it.

This is an alias to the server.listen() method in the version of Node.js running, so consult the Node.js documentation for all the different variations. The most common signature is app.listen(port).

app.use(fn)

Use a function on the app, where the function represents a middleware. The function will be invoked for every request in the order that app.use is called. The function is called with three arguments:

app.use((req, res, next) => {
  // req is the Node.js http request object
  // res is the Node.js http response object
  // next is a function to call to invoke the next middleware
});

In addition to a plan function, the fn argument can also be a Node.js HTTP server instance or another Connect app instance.

app.use(route, fn)

Use a function on the app, where the function represents a middleware. The function will be invoked for every request in which the URL (req.url property) starts with the given route string in the order that app.use is called. The function is called with three arguments:

app.use('/foo', (req, res, next) => {
  // req is the Node.js http request object
  // res is the Node.js http response object
  // next is a function to call to invoke the next middleware
});

In addition to a plan function, the fn argument can also be a Node.js HTTP server instance or another Connect app instance.

The route is always terminated at a path separator (/) or a dot (.) character. This means the given routes /foo/ and /foo are the same and both will match requests with the URLs /foo, /foo/, /foo/bar, and /foo.bar, but not match a request with the URL /foobar.

The route is matched in a case-insensitive manner.

In order to make middleware easier to write to be agnostic of the route, when the fn is invoked, the req.url will be altered to remove the route part (and the original will be available as req.originalUrl). For example, if fn is used at the route /foo, the request for /foo/bar will invoke fn with req.url === '/bar' and req.originalUrl === '/foo/bar'.

Running Tests

npm install
npm test

Credits

This project builds on the original Connect and would not exist without the work of its maintainers and contributors.

List of all contributors

License

MIT

About

An actively maintained fork of Connect.

Resources

License

Security policy

Stars

Watchers

Forks

Contributors