Я некоторое время использовал Express.js, но до тех пор, пока на днях я не знал о изящных Router.Param метод. Это позволяет выполнить обратный вызов, если на маршруте присутствует определенный параметр.
const express = require("express");
const app = express();
const router = express.Router();
route.param('user', function(req, res, next) {
// if ":user" placeholder in any of the router's route definitions
// it will be intercepted by this middleware
const user = { id: 1, name: 'Mirko' };
req.user = user;
next();
});
router.get("/:user", function(req, res) {
// req.user will be populated with { id: 1, name: 'Mirko' }
return res.json({ result: req.user });
});
app.use("/api/users", router); app.listen(3000);
Это довольно полезная функция, как это потому, что часто у вас будет маршрутизатор, который постоянно выбирает модель из базы данных для дальнейших действий. Если ничего другого это действительно не очищает код.
Но что, если у нас немного креативен с этой функцией. Первое, что пришло на мой взгляд, состоит в том, чтобы иметь какую-то «процесс регистрации связывания», а затем динамически привязать параметры Accross приложение. С рамками, такой как Laravel (BTW Laravel поддерживает RMB и был вдохновением для этого поста – кредита, где должным образом) Есть определенные конвенции о моделях и их месте. Мы будем полагаться на конфигурацию по конвенции и указать функции модели модели.
Конечный результат выглядит что-то подобное:
const express = require("express");
const app = express();
const assert = require("assert");
const router = express.Router();
// if you use your imagination getUser and getPost execute a select
// query towards our database and get real data
function getUser(id) {
return Promise.resolve({ id: 1, name: "Mirko" });
}
function getPost(id) {
return Promise.resolve({ id: 1, title: "Express.js is cool" });
}
const bindings = [
{ param: "user", handler: getUser },
{ param: "post", handler: getPost }
];
function handleParam({ param, handler }) {
// just a sanity check to make sure we have what we need
assert(param, "Binding mush have a param");
assert(handler, "Binding must have a handler");
// second argument to `route.param` must be a function
// of similar signature to a normal middleware with exception of
// having an additional parameter which represents the value of placeholder
return function(req, res, next, id) {
return handler(id)
.then(model => {
// we assign the db model to request object for future use
req[param] = model;
next();
})
.catch(err => {
// any errors thrown by handler will be passed to express error handler
next(err);
});
};
}
bindings.forEach(function(binding) {
router.param(binding.param, handleParam(binding));
});
router.get("/:user/posts/:post", function(req, res) {
return res.json({ user: req.user, post: req.post });
});
router.get("/:user", function(req, res) {
return res.json({ result: req.user });
});
app.use("/api/users", router);
app.listen(3000);
Если вы выполняете это локально навигация по http://localhost: 3000/API/Пользователи/1/Сообщения/1 В вашем браузере и проверьте результат.