대략 다음과 같은 REST 엔드 포인트를 원한다고 가정하십시오.
/user/
/user/user_id
/user/user_id/items/
/user/user_id/items/item_id
각각의 CRUD는 의미가 있습니다. 예를 들어, / user POST는 새 사용자를 작성하고 GET은 모든 사용자를 가져옵니다. / user / user_id GET은 한 명의 사용자 만 가져옵니다.
항목은 사용자마다 다르므로 user_id ( 특정 사용자) 아래에 놓습니다 .
이제 익스프레스 라우팅을 모듈화하기 위해 몇 가지 라우터 인스턴스를 만들었습니다. 사용자를위한 라우터와 아이템을위한 라우터가 있습니다.
var userRouter = require('express').Router();
userRouter.route('/')
.get(function() {})
.post(function() {})
userRouter.route('/:user_id')
.get(function() {})
var itemRouter = require('express').Router();
itemRouter.route('/')
.get(function() {})
.post(function() {})
itemRouter.route('/:item_id')
.get(function() {})
app.use('/users', userRouter);
// Now how to add the next router?
// app.use('/users/', itemRouter);
의 URL item
은의 URL 계층 구조의 하위 항목입니다 user
. 이제 /users
userRouter에 대한 것이지만 itemRouter에 대한보다 구체적인 경로는 /user/*user_id*/items/
무엇입니까? 또한 가능한 경우 item_uter에서도 user_id에 액세스 할 수 있기를 바랍니다.
답변
라우터를 사용하거나 사용하지 않고 다른 라우터에 미들웨어 로 연결하여 라우터를 중첩 할 수 있습니다 params
.
상위 라우터에서 {mergeParams: true}
액세스하려면 하위 라우터로 전달해야 params
합니다.
mergeParams
Express4.5.0
에 도입되었습니다 (2014 년 7 월 5 일)
이 예에서는 경로 에 itemRouter
연결됩니다.userRouter
/:userId/items
가능한 경로는 다음과 같습니다.
GET /user
-> hello user
GET /user/5
-> hello user 5
GET /user/5/items
-> hello items from user 5
GET /user/5/items/6
->hello item 6 from user 5
var express = require('express');
var app = express();
var userRouter = express.Router();
// you need to set mergeParams: true on the router,
// if you want to access params from the parent router
var itemRouter = express.Router({mergeParams: true});
// you can nest routers by attaching them as middleware:
userRouter.use('/:userId/items', itemRouter);
userRouter.route('/')
.get(function (req, res) {
res.status(200)
.send('hello users');
});
userRouter.route('/:userId')
.get(function (req, res) {
res.status(200)
.send('hello user ' + req.params.userId);
});
itemRouter.route('/')
.get(function (req, res) {
res.status(200)
.send('hello items from user ' + req.params.userId);
});
itemRouter.route('/:itemId')
.get(function (req, res) {
res.status(200)
.send('hello item ' + req.params.itemId + ' from user ' + req.params.userId);
});
app.use('/user', userRouter);
app.listen(3003);
답변
관리 가능한 중첩 경로 …
Express 4에서 매우 관리 가능한 방식으로 중첩 된 경로를 수행하는 특정 예를 원했고 이것이 “표현 된 경로 중 가장 빠른”검색 결과입니다. 예를 들어 분해해야 할 경로가 많은 API가 있습니다.
./index.js :
var app = require('express')();
// anything beginning with "/api" will go into this
app.use('/api', require('./routes/api'));
app.listen(3000);
./routes/api/index.js :
var router = require('express').Router();
// split up route handling
router.use('/products', require('./products'));
router.use('/categories', require('./categories'));
// etc.
module.exports = router;
./routes/api/products.js :
var router = require('express').Router();
// api/products
router.get('/', function(req, res) {
res.json({ products: [] });
});
// api/products/:id
router.get('/:id', function(req, res) {
res.json({ id: req.params.id });
});
module.exports = router;
폴더 구조의 중첩 예
“중첩 폴더 구조”에 대한 의견을 발견했습니다. 그러나 이것이 명확하지는 않기 때문에 아래 섹션을 추가했습니다. 다음 은 route 에 대한 중첩 폴더 구조 의 특정 예입니다 .
index.js
/api
index.js
/admin
index.js
/users
index.js
list.js
/permissions
index.js
list.js
이것은 노드의 작동 방식에 대한 일반적인 예입니다. 디렉토리 기본값으로 웹 페이지에서 “index.html”이 작동하는 방식과 유사하게 폴더에서 “index.js”를 사용하는 경우 진입 점을 코드로 변경하지 않고 재귀에 따라 조직을 쉽게 확장 할 수 있습니다. “index.js”는 디렉토리에서 require 를 사용할 때 액세스되는 기본 문서 입니다.
index.js의 내용
const express = require('express');
const router = express.Router();
router.use('/api', require('./api'));
module.exports = router;
/api/index.js의 내용
const express = require('express');
const router = express.Router();
router.use('/admin', require('./admin'));
module.exports = router;
/api/admin/index.js의 내용
const express = require('express');
const router = express.Router();
router.use('/users', require('./users'));
router.use('/permissions', require('./permissions'));
module.exports = router;
/api/admin/users/index.js의 내용
const express = require('express');
const router = express.Router();
router.get('/', require('./list'));
module.exports = router;
여기에 일부 DRY 문제가있을 수 있지만 문제를 캡슐화하는 데 적합합니다.
참고로, 최근에 나는 actionhero에 들어가서 REST 패러다임을 뒤집는 진정한 프레임 워크 올인원과 같은 완전한 기능의 w / 소켓 및 작업 인 것을 발견했습니다. 당신은 아마 명시 적 / 알몸으로 그것을 확인해야합니다.
답변
var userRouter = require('express').Router();
var itemRouter = require('express').Router({ mergeParams: true });
userRouter.route('/')
.get(function(req, res) {})
.post(function(req, res) {})
userRouter.route('/:user_id')
.get(function() {})
itemRouter.route('/')
.get(function(req, res) {})
.post(function(req, res) {})
itemRouter.route('/:item_id')
.get(function(req, res) {
return res.send(req.params);
});
app.use('/user/', userRouter);
app.use('/user/:user_id/item', itemRouter);
질문의 두 번째 부분의 핵심은 mergeParams 옵션을 사용하는 것입니다
var itemRouter = require('express').Router({ mergeParams: true });
에서 /user/jordan/item/cat
I reponse를 얻을 :
{"user_id":"jordan","item_id":"cat"}
답변
@Jason Sebring 솔루션을 사용하고 Typescript에 적합합니다.
server.ts
import Routes from './api/routes';
app.use('/api/', Routes);
/api/routes/index.ts
import { Router } from 'express';
import HomeRoutes from './home';
const router = Router();
router.use('/', HomeRoutes);
// add other routes...
export default router;
/api/routes/home.ts
import { Request, Response, Router } from 'express';
const router = Router();
router.get('/', (req: Request, res: Response) => {
res.json({
message: 'Welcome to API',
});
});
export default router;
답변
try to add { mergeParams: true } look to simple example which it middlware use it in controller file getUser at the same for postUser
const userRouter = require("express").Router({ mergeParams: true });
export default ()=>{
userRouter
.route("/")
.get(getUser)
.post(postUser);
userRouter.route("/:user_id").get(function () {});
}
답변
라우터는 하나만 필요하며 다음과 같이 사용하십시오.
router.get('/users');
router.get('/users/:user_id');
router.get('/users/:user_id/items');
router.get('/users/:user_id/items/:item_id');
app.use('api/v1', router);