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-parserto parse cookies e.g. for sessions -
body-parserto handle JSON bodies -
corsto mitigate CORS-related headaches -
morganfor 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 })
]
you can call this file
middlewares.jsto 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')
and run
node index.js
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"*
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
}),
...
Let me know on Twitter if you have questions or found better ways to handle middlewares!
Top comments (6)
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?Absolutely yes 👍
Interesting approach, I've never seen this before. Looks very nice!
Thanks!
Nice article! It's really helpful to make your code clean. Thanks ...
Glad it was helpful!