Przypuśćmy, że chcę mieć odpoczynek punktów końcowych, które wyglądają mniej więcej tak:
/user/
/user/user_id
/user/user_id/items/
/user/user_id/items/item_id
Crud na każdy, jeśli ma sens. Na przykład / User Post tworzy nowego użytkownika, pobieraj pobieranie wszystkich użytkowników. / Użytkownik / User_id Get Fetches tylko tego użytkownika.
Przedmioty są specyficzne dla użytkownika, więc umieściłem je pod user_id , który jest konkretnym użytkownikiem.
Teraz, aby wykonać ekspresowe routing modułowy, wykonałem kilka instancji routera. Jest router dla użytkownika i router dla przedmiotu.
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 do item
jest potomkami hierarchii adresów URL user
. Teraz jak uzyskać adres URL z /users
cokolwiek do Użytkownika, ale bardziej konkretna trasa /user/*user_id*/items/
do ItemOutera? A także, chciałbym, aby user_id był dostępny do ItemRoutera, jeśli to możliwe.
5 odpowiedzi
Możesz gniazdować routery, dołączając je jako Middleware na innym routerze, z lub bez params
.
Musisz przejść {mergeParams: true}
do routera dla dzieci, jeśli chcesz uzyskać dostęp do params
z routera macierzystego.
mergeParams
został wprowadzony w Express 4.5.0
(lipca 5 2014)
W tym przykładzie itemRouter
jest przymocowany do userRouter
na trasie /:userId/items
Spowoduje to następujące możliwe trasy:
GET /user
- & gt; hello user
GET /user/5
- & gt; hello user 5
GET /user/5/items
- & gt; hello items from user 5
GET /user/5/items/6
- & gt; 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);
Zarządzanie zagnieżdżonymi trasami ...
Chciałem konkretny przykład wykonania zagnieżdżonych tras w bardzo łatwy sposób w ekspresji 4, a to był górny wynik wyszukiwania dla "zagnieżdżonych tras w ekspresji". Oto interfejs API, który miałby wiele tras, które musiałyby zostać rozbite na przykład.
./ index.js:
var app = require('express')();
// anything beginning with "/api" will go into this
app.use('/api', require('./routes/api'));
app.listen(3000);
./ trasy / 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;
./ trasy / 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;
Przykład gniazdowy w strukturze folderu
Zauważyłem kilka komentarzy na temat "zagnieżdżania struktury folderów". Obsługuje się, jednak nie jest oczywiste, więc dodałem poniższy sekcję. Oto określony przykład struktury folderu dla tras .
index.js
/api
index.js
/admin
index.js
/users
index.js
list.js
/permissions
index.js
list.js
Jest to bardziej ogólny przykład, jak działa węzeł. Jeśli używasz "index.js" w folderach, podobnie jak "index.html" działa na stronach internetowych dla domyślnych katalogów, będzie to łatwe w skalowaniu organizacji opartej na rekurencji bez zmiany punktów wpisowych do kodu. "index.js" jest domyślnym dokumentem dostępnym podczas korzystania z wymagać w katalogu.
Spis treści index.js
const express = require('express');
const router = express.Router();
router.use('/api', require('./api'));
module.exports = router;
Spis treści /Pi/index.js
const express = require('express');
const router = express.Router();
router.use('/admin', require('./admin'));
module.exports = router;
Zawartość / hapi/admin/index.js
const express = require('express');
const router = express.Router();
router.use('/users', require('./users'));
router.use('/permissions', require('./permissions'));
module.exports = router;
Spis treści /api/admin/users/index.js
const express = require('express');
const router = express.Router();
router.get('/', require('./list'));
module.exports = router;
Prawdopodobnie istnieje kilka suchych problemów, ale nadaje się dobrze do kapsułki obaw.
FYI, ostatnio dostałem się do Actionhero i stwierdziłem, że jest to pełne funkcjonalne w / gniazda i zadania, bardziej jak prawdziwa ramy all-in-one odwracając paradygmat resztę na głowie. Prawdopodobnie powinieneś to sprawdzić nad nim w / Express.
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);
Kluczem do drugiej części twojego pytania jest użycie opcji MergeParams
var itemRouter = require('express').Router({ mergeParams: true });
Z /user/jordan/item/cat
otrzymuję odpowiedź:
{"user_id":"jordan","item_id":"cat"}
Korzystanie z rozwiązania @jason Sebring i dostosowanie do maszynopisu.
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;
Potrzebujesz tylko jednego routera i użyć go tak:
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);