DEV Community

Cover image for The cleanest way to maintain connect / express middlewares in Node.js
Christian
Christian

Posted on • Originally published at cri.dev

The cleanest way to maintain connect / express middlewares in Node.js

Originally posted on cri.dev

I want to share how I maintain my connect / express middlewares for simple HTTP APIs in Node.js

The code snippets below are taken from pomodoro.cc api source code.

Defining the middlewares

Below you can see a simple file containing all middlewares, exported as an array.

In this example the middlewares in use are:

  • cookie-parser to parse cookies e.g. for sessions
  • body-parser to handle JSON bodies
  • cors to mitigate CORS-related headaches
  • morgan for logging

the order of connect middlewares is important, as it can be seen as a pipeline of handlers, executed one by one.

this is why the handling of CORS requests must happen before parsing cookies or the request body for instance.

const cookieParser = require('cookie-parser')
const bodyParser = require('body-parser')
const cors = require('cors')
const morgan = require('morgan')

module.exports = [
  morgan(':status\t :method\t :response-time ms\t :date[clf]\t :url\t\t'),
  cors({
    origin: true,
    methods: ['HEAD', 'GET', 'POST', 'PUT', 'PATCH', 'DELETE'],
    allowedHeaders: ['x-now-id', 'x-now-trace', 'x-powered-by', 'Origin', 'Accept', 'Content-Type', 'Set-Cookie'],
    credentials: true
  }),
  cookieParser(),
  bodyParser.json({}),
  bodyParser.urlencoded({ extended: true })
]
Enter fullscreen mode Exit fullscreen mode

you can call this file middlewares.js to follow along with the code

Using the middlewares

In the following code snippet you can see an example usage of the middlewares, in a bare-bone connect / express application in Node.js

const app = require('express')()
const middlewares = require('./middlewares')
app.use(...middlewares)
app.post('/hello', (req, res) => res.json(`hello ${req.body.name}`))
app.listen(process.env.HTTP_PORT || 3000)
console.log('listening on http://localhost:3000')
Enter fullscreen mode Exit fullscreen mode

and run

node index.js
Enter fullscreen mode Exit fullscreen mode

Making a request

Once the server is listening on port 3000, you can run the following and see the middlewares in action with curl!

You will get an output similar to this one:

> curl -vv -X POST -H 'Content-Type: application/json' http://localhost:3000/hello --data '{"name": "chris"}'

...
...
< HTTP/1.1 200 OK
< X-Powered-By: Express
< Access-Control-Allow-Credentials: true
< Content-Type: application/json; charset=utf-8
< Content-Length: 13
< Vary: Origin
< ETag: W/"d-WPAgGvBxJ3QraEI06EWKezzLidE"
< Date: Tue, 28 Jan 2020 22:36:18 GMT
< Connection: keep-alive
<

"hello chris"*
Enter fullscreen mode Exit fullscreen mode

Notice the headers Access-Control-Allow-Credentials?

That's for example where the CORS middleware comes in, that is currently configured to allow credentials for CORS requests.

As you can see in middlewares.js:

...
  cors({
    origin: true,
    methods: ['HEAD', 'GET', 'POST', 'PUT', 'PATCH', 'DELETE'],
    allowedHeaders: ['x-now-id', 'x-now-trace', 'x-powered-by', 'Origin', 'Accept', 'Content-Type', 'Set-Cookie'],
    credentials: true
  }),
...
Enter fullscreen mode Exit fullscreen mode

Let me know on Twitter if you have questions or found better ways to handle middlewares!

Top comments (6)

Collapse
 
kmistele profile image
Kyle Mistele

Really cool! Definitely a better option compared to using 30-odd lines of app.js for middlewares. Does the ... operator guarantee that the properties of the module's exports will be expanded in the order that they're defined?

Collapse
 
christianfei profile image
Christian

Absolutely yes 👍

Collapse
 
dmahely profile image
Doaa Mahely

Interesting approach, I've never seen this before. Looks very nice!

Collapse
 
christianfei profile image
Christian

Thanks!

Collapse
 
nabaraj profile image
Nabaraj saha • Edited

Nice article! It's really helpful to make your code clean. Thanks ...

Collapse
 
christianfei profile image
Christian

Glad it was helpful!