💼 express-briefcase
Include metadata in Express.js response json such as errors, warnings and pagination
Installation
npm install express-briefcase
Using the middleware
Using default behavior:
const express = require('express');
const app = express();
app.use(briefcase());
Adding custom metadata:
const express = require('express');
const uuid = require('uuid');
const app = express();
app.use(
briefcase(shell => {
shell.requestReferenceId = uuid.v4();
if (shell.statusClass === '5xx') {
shell.apology = 'Sorry about that!';
}
return shell;
})
);
Accessing the res object:
const express = require('express');
const uuid = require('uuid');
const app = express();
app.use(
briefcase(function (shell) {
// Inside your customizer function, "this" is express's "res" object
// Note that we must use the "function" keyword, not an arrow function
shell.statusMessage = this.statusMessage;
return shell;
})
);
Using the new res methods
res.decoratedJson()
Using app.get('/user/:id', async (req, res) => {
const user = await getUser(req.params.id);
res.decoratedJson(user);
});
Resulting response JSON
{
"date": "2022-01-03T04:48:00.095Z",
"took": 451,
"status": 200,
"statusClass": "2xx",
"success": true,
"errors": [],
"warnings": [],
"new": null,
"pagination": null,
"payload": {
"id": 123,
"fname": "Joe",
"lname": "User"
}
}
res.error()
Using app.get('/user/:id', async (req, res) => {
const user = await getUser(req.params.id);
if (user === null) {
// Note: error can be a string or instance of Error
res.error('User not found');
res.status(404);
}
res.decoratedJson(user);
});
Resulting response JSON
{
"date": "2022-01-03T04:48:00.095Z",
"took": 452,
"status": 404,
"statusClass": "4xx",
"success": false,
"errors": ["User not found"],
"warnings": [],
"new": null,
"pagination": null,
"payload": null
}
res.devError()
Using Same as res.error() except that the error string will
only be added if process.env.NODE_ENV === 'development'
.
res.warn()
Using app.get('/user/:id', async (req, res) => {
if (req.query.role) {
res.warn('Passing role to /user/:id is deprecated.');
}
const user = await getUser(req.params.id);
res.decoratedJson(user);
});
Resulting response JSON
{
"date": "2022-01-03T04:48:00.095Z",
"took": 458,
"status": 200,
"statusClass": "4xx",
"success": true,
"errors": [],
"warnings": ["Passing role to /user/:id is deprecated."],
"new": null,
"pagination": null,
"payload": {
"id": 123,
"fname": "Joe",
"lname": "User"
}
}
res.new()
Using app.post('/user', async (req, res) => {
const { newId } = await createUser(req.body);
res.new({ id: newId, url: `/users/${newId}` });
res.decoratedJson();
});
Resulting response JSON
{
"date": "2022-01-03T04:48:00.095Z",
"took": 458,
"status": 201,
"statusClass": "2xx",
"success": true,
"errors": [],
"warnings": [],
"new": {
"id": 123,
"url": "/users/123"
},
"pagination": null,
"payload": null
}
res.total()
Using app.get('/users/search', async (req, res) => {
const { list, total } = await getUsers({
name: req.query.name,
page: req.query.page,
limit: 25,
});
res.total({ total, page: req.query.page, perPage: 25 });
res.decoratedJson(user);
});
Resulting response JSON
{
"date": "2022-01-03T04:48:00.095Z",
"took": 454,
"status": 200,
"statusClass": "2xx",
"success": true,
"errors": [],
"warnings": [],
"new": null,
"pagination": {
"perPage": 25,
"page": 2,
"total": 104,
"numPages": 5,
"hasNextPage": true,
"prev": "/users/search?name=John&page=1",
"next": "/users/search?name=John&page=3"
},
"payload": [
{
"id": 576,
"fname": "Jennifer",
"lname": "Johnson"
},
"..."
]
}
Unit Tests and Code Coverage
Powered by jest
npm test
npm run coverage
Contributing
Contributions are welcome. Please open a GitHub ticket for bugs or feature requests. Please make a pull request for any fixes or new code you'd like to be incorporated.
License
Open Source under the ISC License.