Stop reinventing server middlewares and take advantage of Express ecosystem
Tags: node, javascript, frontend, showdev
Published: 2020-03-21 16:14:05

---
title: Stop reinventing server middlewares and take advantage of Express ecosystem
published: true
description: 
tags: node, javascript, frontend, showdev
---



# TL;DR

[flow-middleware](https://github.com/piglovesyou/flow-middleware) creates a portable server handler from [any of Express middlewares](https://expressjs.com/en/resources/middleware.html). You can run all the adapters of [express-session](https://github.com/expressjs/session#compatible-session-stores) and [Passport.js stategies](http://www.passportjs.org/packages/) in your [Next.js](https://nextjs.org/docs/api-routes/introduction), [micro](https://github.com/zeit/micro#usage) and [Node native server](https://nodejs.org/api/http.html#http_http_createserver_options_requestlistener) today.

```typescript
import flow from 'flow-middleware';

const handle = flow(
    // Pass Express middlewares
    cookieParser(),
    session({ secret: 'x' }),
    flash(),
    (_reqProxy, resProxy, next) => {
        resProxy.redirect('/');
    }
);

// Handles Node native IncomingMessage and ServerResponse
handle(req, res);
```

[Checkout the Next.js example](https://github.com/piglovesyou/nextjs-passport-oauth-example) with [Passport.js](http://www.passportjs.org/) integration.

# Why

As people start using a new Node server library other than [Express](https://expressjs.com/), they encounter a lack of middlewares that Express already has, which has been well tested and production-ready many years ago. Some of them try to shape a brand new ecosystem on the new island and some just sail back to Express.

Let's start from admitting Express is one of the most successful, beautifully designed and battle-tested software in the Node-based software. Don't forget its **hundreds of outstanding middlewares** have been born upon it.

Then why you can't use them? The answers will be summarized into these two:

* It just can't run since they depend on Express's `req.param()` and `res.redirect()`. I don't want to hack to make them work in my _${Your favorite server name comes here}_.
* Pollution. [Express officially recommends](https://expressjs.com/en/guide/writing-middleware.html) middlewares to extend object properties such as `req.session = {}` and `req.flash = fn`, where my _${Your favorite server}_ leaves them clean. Plus, dynamic extensions don't fit today of the TypeScript era.

Yeah, yeah. Then how to solve them both?

# How

JavaScript `Proxy`.

Wrapping `req` and `res` by `Proxy` that splits Node native and Express properties to be accessed. Express exports clean prototypes we can intercept middleware's calls with. It also lets middlewares to call native methods like `res.writeHead()` and `res.end()` so native objects properly embed HTTP info like headers and send the response back.

The handler, in the end, returns the proxy objects with like `req.session` and `req.user` so you can still use them after the middlewares go through.

![](https://github.com/piglovesyou/flow-middleware/raw/master/resource/flow-middleware.png)

# Getting started

Install it with Express.

```bash
yarn add flow-middleware express
```

### flow(...middlewares)

A function `flow` creates an http handler from some Express middlewares, processed from left to right of arguments.

```typescript
import flow from 'flow-middleware';
import { ok } from "assert";
import { createServer } from 'http';
import cookieParser from 'cookie-parser';
import session from 'express-session';
import flash from 'express-flash';

// Creates an async function that handles req and res.
const handle = flow(
    cookieParser(),
    session({ secret: 'x' }),
    flash(),
    (reqProxy, _resProxy, next) => {
    
        // Our wrapped objects provide accessors
        // that Express middlewares extended💪
        ok(reqProxy.cookies);
        ok(reqProxy.session);
        ok(reqProxy.flash);
        next();
    }
);

createServer(async (req, res) => {
  
    // Let's run the Express middlewares🚀
    const [ reqProxy, resProxy ] = await handle(req, res);

    // Native objects are clean thanks to our proxy✨
    ok(req.cookies === undefined);
    ok(req.session === undefined);
    ok(req.flash === undefined);

    // You still can access to Express properties here🚚
    ok(reqProxy.cookies);
    ok(reqProxy.session);
    ok(reqProxy.flash);
    ok(resProxy.cookie);
    ok(resProxy.redirect);

    res.end('Hello!');
}).listen(3000);
```

[Check out `compose()` function](https://github.com/piglovesyou/flow-middleware/#composemiddlewaresmiddlewares) to flexibly share middlewares between multiple endpoints.

# Conclusion

It takes years for a new framework to have bug-free middlewares for all the sessions, OAuth and logger adapters. Why don't you take advantage of Express ecosystem, one of the most stable solutions for Node.js?