Я некоторое время использовал 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 В вашем браузере и проверьте результат.