Рубрики
Без рубрики

Express.js: Модель маршрута Привязка

Очистите контроллеры Express.js и получите свои модели из БД и готовы, если они присутствуют в определении маршрута.

Автор оригинала: Mirko Jotic.

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