Express Resource Router Middleware
resource-router-middleware provides a concise, declarative way to define RESTful API endpoints for Express applications. It allows developers to configure a full CRUD (Create, Read, Update, Delete) resource using a single object literal, mapping HTTP methods (GET, POST, PUT, DELETE) to corresponding handler functions (list, create, read, update, delete). The current stable version is 0.7.0, released in 2017. The project appears to be unmaintained, with its last commit in 2020, suggesting an abandoned release cadence. Its key differentiator is simplifying the definition of standard REST resources, abstracting away individual route declarations and integrating with Express's parameter loading mechanisms, which can lead to more readable and organized route definitions compared to manual `app.get()`, `app.post()` etc.
Common errors
-
TypeError: app.use() requires a middleware function but got a Object
cause Attempting to pass the result of `resource()` directly to `app.use()` without mounting it as a router.fixEnsure that `resource()` is called and its return value (which is an Express Router) is passed to `app.use()` or `app.route()`. The quickstart example demonstrates this correctly: `app.use('/users', resource(...));`. -
Error: Can't set headers after they are sent to the client.
cause Sending multiple responses within a single request handler, or trying to send a response after `next()` has been called and another handler has already sent a response.fixVerify that your `list`, `create`, `read`, `update`, and `delete` handlers, as well as the `load` function's error callback, send only one response per request. If `callback('error')` is invoked, subsequent `res.json()` calls will fail. Ensure explicit `return` statements after sending a response or calling `next()`.
Warnings
- deprecated The project appears to be abandoned since its last release in 2017 (v0.7.0) and last commit in 2020. It's not actively maintained and may not be compatible with recent versions of Node.js or Express without issues.
- gotcha The `load` function uses a Node.js-style callback (`callback(err, data)`). Modern Express middleware often uses Promises or `async/await`. Mixing these patterns without careful handling can lead to difficult-to-debug issues, especially with error propagation.
- gotcha The package's use of `req.params[this.id]` and direct manipulation of `req` properties (`req.user`) might conflict with TypeScript or stricter linting rules without proper declaration merging for `Request` types.
Install
-
npm install resource-router-middleware -
yarn add resource-router-middleware -
pnpm add resource-router-middleware
Imports
- resource
import { resource } from 'resource-router-middleware';import resource from 'resource-router-middleware';
- resource
const resource = require('resource-router-middleware');
Quickstart
import express from 'express';
import resource from 'resource-router-middleware';
const app = express();
app.use(express.json()); // For parsing application/json
const users = [];
// A simple mock for `users` data
for (let i = 0; i < 3; i++) {
users.push({ id: String(i), name: `User ${i}`, email: `user${i}@example.com` });
}
app.use('/users', resource({
mergeParams: true,
id: 'user',
load(req, id, callback) {
const user = users.find(u => u.id === id);
const err = user ? null : 'Not found';
callback(err, user);
},
list({ params }, res) {
res.json(users);
},
create({ body }, res) {
const newUser = { ...body, id: String(users.length) };
users.push(newUser);
res.status(201).json(newUser);
},
read({ user }, res) {
res.json(user);
},
update({ user, body }, res) {
const index = users.indexOf(user);
if (index !== -1) {
for (let key in body) {
if (key !== 'id') {
user[key] = body[key];
}
}
users[index] = user;
res.status(204).send();
} else {
res.status(404).send('Not Found');
}
},
delete({ user }, res) {
const index = users.indexOf(user);
if (index !== -1) {
users.splice(index, 1);
res.status(204).send();
} else {
res.status(404).send('Not Found');
}
}
}));
app.get('/', (req, res) => res.send('Welcome to the API! Try /users or /users/0'));
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server running on http://localhost:${PORT}`);
console.log('Available endpoints: /users (GET, POST), /users/:id (GET, PUT, DELETE)');
});