如何将我的 koa 路由拆分成单独的文件?
How can I split my koa routes into separate files?
我正在想办法将我的路线拆分成单独的文件。
目前我有这个,但它不起作用。当我尝试访问 http://localhost:3001/api/things
时,我只得到 Not found
//server.js
var koa = require('koa');
var app = koa();
var router = require('koa-router');
app.use(router(app));
require('./routes')(app);
// routes.js
module.exports = function *(app){
app.use('/api/things', require('./api/things'));
};
// api/things/index.js
var Router = require('koa-router');
var router = new Router({
prefix: '/api/things'
});
router.get('/', function *(){
this.body = [{ name: 'Foo'}, { name: 'Bar' }];
});
module.exports = router;
像这样的东西应该可以工作:
// app.js
var koa = require('koa'),
app = koa();
require('./routes1')(app);
require('./routes2')(app);
app.listen(3000);
// routes1.js
var Router = require('koa-router');
function register (app) {
var router = new Router({
prefix: '/api'
});
router.get('/', ...); // responds to "/api"
router.get('/messages', ...); // responds to "/api/messages"
app.use(router.routes());
app.use(router.allowedMethods());
}
module.exports = register
// routes2.js
var Router = require('koa-router');
function register (app) {
var router = new Router();
router.get('/', ...); // responds to "/"
app.use(router.routes());
app.use(router.allowedMethods());
}
module.exports = register
这是我最终的结果:
//server.js
'use strict';
var koa = require('koa');
var app = koa();
var serve = require('koa-static');
var path = require('path');
var router = require('koa-router');
var cfg = require('./config');
var mw = require('./middleware');
app.use(serve(path.resolve(__dirname, '../client')));
app.use(mw.requestTime('Response-time'));
app.use(router(app));
app.use(cfg.db.connect);
require('./routes')(app);
app.get('/api', function *(){
this.body = 'Welcome to API v1';
});
app.use(cfg.db.close);
app.listen(cfg.env.port);
//routes.js
module.exports = function (app){
app.use(require('./api/things').routes());
};
// api/things/index.js
var Router = require('koa-router');
var router = new Router({
prefix: '/api/things'
});
var ctrl = require('./controllers');
router.get('/', ctrl.list);
router.get('/:id', ctrl.get);
router.post('/', ctrl.post);
router.put('/:id', ctrl.put);
router.del('/:id', ctrl.del);
module.exports = router;
// api/things/controllers.js
var r = require('rethinkdb');
var http = require('http');
var parse = require('co-body');
var ctrl = module.exports = {};
ctrl.list = function *(next){
};
ctrl.get = function *(next){
};
ctrl.post = function *(next){
};
ctrl.put = function *(next){
};
ctrl.del = function *(next){
};
server.js
var app = require('koa')();
var router = require('./routes');
app.use(router.routes());
app.use(router.allowedMethods());
app.listen(3000);
routes.js
var router = require('koa-router')();
router.get('/', function* () {
this.body = 'router test';
});
module.exports = router;
编辑:我更新了下面的代码示例,因为不再维护 npm 上的 koa-router
包。 Koa 团队以 @koa/router
.
的名义对其进行了正式的分叉。
对于阅读本文的任何人,如果他们对如何在 Koa 中做到这一点感到好奇 2.X:
app.js
import Koa from 'koa'
import rootRouter from './routes/root'
import userRouter from './routes/user'
const app = new Koa()
app.use(rootRouter.routes())
app.use(rootRouter.allowedMethods())
app.use(userRouter.routes())
app.use(userRouter.allowedMethods())
export default app
routes/root.js
import Router from '@koa/router'
const router = new Router()
router.get('/', async (ctx, next) => {
ctx.body = 'Hello'
})
export default router
routes/user.js
import Router from '@koa/router'
const router = new Router({ prefix: '/user' })
router.get('/', async (ctx, next) => {
ctx.body = 'Some User'
})
export default router
如果想避免与routes()
和allowedMethods()
重复,可以使用koa-compose
组合中间件。为简单起见,我围绕它制作了一个 wrapper 以简化使用 koa-router
的工作。使用它看起来像这样:
app.js
import Koa from 'koa'
import router from './routes'
const app = new Koa()
app.use(router())
export default app
routes/index.js
import combineRouters from 'koa-combine-routers'
import rootRouter from './root'
import userRouter from './user'
const router = combineRouters(
rootRouter,
userRouter
)
export default router
它会做同样的事情。
我认为 TJ 在做
时牢记的极简主义方法
koa, koa-route, koa-mount
使用您喜欢的方式安装小型独立应用程序的方法:
index.js
var app = require('./app')
app.listen(3000);
app.js
const Koa = require('koa')
const _ = require('koa-route')
const mount = require('koa-mount')
const app = new Koa()
const pets = require('./pets')
// sub apps
app.use(mount('/pets', pets))
// root app
app.use(_.get('/', function(){
this.body = "hello";
}))
module.exports = app;
pets.js
var Koa = require('koa');
var _ = require('koa-route');
var app = new Koa();
app.use(_.get('/', ctx => ctx.body = "pets" ));
app.use(_.get('/:name', (ctx, name) => ctx.body = "pet: "+ name));
module.exports = app;
对于 Koa 2.x 我发现 嵌套路由 带有 前缀 来交付货物,没有额外的包裹。
假设 /api/dogs 和 /api/cats 是所需的结果。
像这样:
app.js
import Koa from 'koa';
import Router from 'koa-router';
import apiRouter from './routes/apiRouter';
const app = new Koa();
app.use(apiRouter.routes(), apiRouter.allowedMethods());
app.listen(3000);
export default app;
routes/apiRouter.js
import Router from 'koa-router'
import dogsRouter from './dogsRouter'
import catsRouter from './catsRouter'
const apiRouter = new Router({ prefix: '/api' })
const nestedRoutes = [dogsRouter, catsRouter]
for (var router of nestedRoutes) {
apiRouter.use(router.routes(), router.allowedMethods())
}
export default apiRouter;
routes/dogsRouter.js
import Router from 'koa-router'
const dogsRouter = new Router({ prefix: '/dogs' });
dogsRouter.get('/', async (ctx, next) => {
ctx.body = 'Dogs be here'
});
export default dogsRouter;
routes/catsRouter.js
import Router from 'koa-router'
const catsRouter = new Router({ prefix: '/cats' });
catsRouter.get('/', async (ctx, next) => {
ctx.body = 'Cats be here'
});
export default catsRouter;
您可以将所有路由放在一个名为 routes 的文件夹中,然后遍历该文件夹中的所有文件,需要它们并初始化。这样对于任何新路线,只需在路线文件夹中创建一个文件即可。
所以像这样:
index.js
const Koa = require("koa");
const logger = require("koa-logger");
const bodyParser = require("koa-bodyparser");
const app = new Koa();
app.use(logger());
app.use(bodyParser());
require("./routes")(app);
const server = app.listen(config.server.port);
module.exports = server;
/routes/index.js
const fs = require("fs");
const path = require("path");
const baseName = path.basename(module.filename);
const routes = fs
.readdirSync(path.join(__dirname))
.filter(
file =>
file.indexOf(".") !== 0 &&
file !== baseName &&
file.slice(-3) === ".js"
)
.map(file => require(path.join(__dirname, file)));
module.exports = function(app) {
for (var router of routes) {
app.use(router.routes());
}
};
然后在 /routes 文件夹中你会喜欢
/routes/user.js
/routes/customer.js
这些都是路由器出口,例如
/routes/auth.js
const Router = require("koa-router");
const authControllers = require("../controllers/auth");
const {
jwtAuth,
login,
register,
forgotPassword,
resetPassword,
getAuthenticatedUser
} = authControllers;
const router = new Router({ prefix: "/auth" });
router.post("/register", register);
router.post("/login", login);
router.post("/forgot-password", forgotPassword);
router.post("/reset-password/:resetToken", resetPassword);
router.get("/profile", jwtAuth, getAuthenticatedUser);
module.exports = router;
类似,但我真正需要的是:
app.js
"use strict";
import Koa from 'koa';
const app = new Koa();
import Router from 'koa-router';
const router = new Router();
import mount from 'koa-mount';
import routes from "./router/index.mjs";
app.use(mount(routes));
app.use(router.routes());
app.listen(3000, () => console.log("Listening on port: 3000"));
router/index.mjs
"use strict";
import Koa from 'koa';
const app = new Koa();
import Router from 'koa-router';
const router = new Router();
router.get('/', async (ctx, next) => {
ctx.body = {success: true};
await next();
});
app.use(router.routes());
export default app;
我正在想办法将我的路线拆分成单独的文件。
目前我有这个,但它不起作用。当我尝试访问 http://localhost:3001/api/things
Not found
//server.js
var koa = require('koa');
var app = koa();
var router = require('koa-router');
app.use(router(app));
require('./routes')(app);
// routes.js
module.exports = function *(app){
app.use('/api/things', require('./api/things'));
};
// api/things/index.js
var Router = require('koa-router');
var router = new Router({
prefix: '/api/things'
});
router.get('/', function *(){
this.body = [{ name: 'Foo'}, { name: 'Bar' }];
});
module.exports = router;
像这样的东西应该可以工作:
// app.js
var koa = require('koa'),
app = koa();
require('./routes1')(app);
require('./routes2')(app);
app.listen(3000);
// routes1.js
var Router = require('koa-router');
function register (app) {
var router = new Router({
prefix: '/api'
});
router.get('/', ...); // responds to "/api"
router.get('/messages', ...); // responds to "/api/messages"
app.use(router.routes());
app.use(router.allowedMethods());
}
module.exports = register
// routes2.js
var Router = require('koa-router');
function register (app) {
var router = new Router();
router.get('/', ...); // responds to "/"
app.use(router.routes());
app.use(router.allowedMethods());
}
module.exports = register
这是我最终的结果:
//server.js
'use strict';
var koa = require('koa');
var app = koa();
var serve = require('koa-static');
var path = require('path');
var router = require('koa-router');
var cfg = require('./config');
var mw = require('./middleware');
app.use(serve(path.resolve(__dirname, '../client')));
app.use(mw.requestTime('Response-time'));
app.use(router(app));
app.use(cfg.db.connect);
require('./routes')(app);
app.get('/api', function *(){
this.body = 'Welcome to API v1';
});
app.use(cfg.db.close);
app.listen(cfg.env.port);
//routes.js
module.exports = function (app){
app.use(require('./api/things').routes());
};
// api/things/index.js
var Router = require('koa-router');
var router = new Router({
prefix: '/api/things'
});
var ctrl = require('./controllers');
router.get('/', ctrl.list);
router.get('/:id', ctrl.get);
router.post('/', ctrl.post);
router.put('/:id', ctrl.put);
router.del('/:id', ctrl.del);
module.exports = router;
// api/things/controllers.js
var r = require('rethinkdb');
var http = require('http');
var parse = require('co-body');
var ctrl = module.exports = {};
ctrl.list = function *(next){
};
ctrl.get = function *(next){
};
ctrl.post = function *(next){
};
ctrl.put = function *(next){
};
ctrl.del = function *(next){
};
server.js
var app = require('koa')();
var router = require('./routes');
app.use(router.routes());
app.use(router.allowedMethods());
app.listen(3000);
routes.js
var router = require('koa-router')();
router.get('/', function* () {
this.body = 'router test';
});
module.exports = router;
编辑:我更新了下面的代码示例,因为不再维护 npm 上的 koa-router
包。 Koa 团队以 @koa/router
.
对于阅读本文的任何人,如果他们对如何在 Koa 中做到这一点感到好奇 2.X:
app.js
import Koa from 'koa'
import rootRouter from './routes/root'
import userRouter from './routes/user'
const app = new Koa()
app.use(rootRouter.routes())
app.use(rootRouter.allowedMethods())
app.use(userRouter.routes())
app.use(userRouter.allowedMethods())
export default app
routes/root.js
import Router from '@koa/router'
const router = new Router()
router.get('/', async (ctx, next) => {
ctx.body = 'Hello'
})
export default router
routes/user.js
import Router from '@koa/router'
const router = new Router({ prefix: '/user' })
router.get('/', async (ctx, next) => {
ctx.body = 'Some User'
})
export default router
如果想避免与routes()
和allowedMethods()
重复,可以使用koa-compose
组合中间件。为简单起见,我围绕它制作了一个 wrapper 以简化使用 koa-router
的工作。使用它看起来像这样:
app.js
import Koa from 'koa'
import router from './routes'
const app = new Koa()
app.use(router())
export default app
routes/index.js
import combineRouters from 'koa-combine-routers'
import rootRouter from './root'
import userRouter from './user'
const router = combineRouters(
rootRouter,
userRouter
)
export default router
它会做同样的事情。
我认为 TJ 在做
时牢记的极简主义方法koa, koa-route, koa-mount
使用您喜欢的方式安装小型独立应用程序的方法:
index.js
var app = require('./app')
app.listen(3000);
app.js
const Koa = require('koa')
const _ = require('koa-route')
const mount = require('koa-mount')
const app = new Koa()
const pets = require('./pets')
// sub apps
app.use(mount('/pets', pets))
// root app
app.use(_.get('/', function(){
this.body = "hello";
}))
module.exports = app;
pets.js
var Koa = require('koa');
var _ = require('koa-route');
var app = new Koa();
app.use(_.get('/', ctx => ctx.body = "pets" ));
app.use(_.get('/:name', (ctx, name) => ctx.body = "pet: "+ name));
module.exports = app;
对于 Koa 2.x 我发现 嵌套路由 带有 前缀 来交付货物,没有额外的包裹。
假设 /api/dogs 和 /api/cats 是所需的结果。
像这样:
app.js
import Koa from 'koa';
import Router from 'koa-router';
import apiRouter from './routes/apiRouter';
const app = new Koa();
app.use(apiRouter.routes(), apiRouter.allowedMethods());
app.listen(3000);
export default app;
routes/apiRouter.js
import Router from 'koa-router'
import dogsRouter from './dogsRouter'
import catsRouter from './catsRouter'
const apiRouter = new Router({ prefix: '/api' })
const nestedRoutes = [dogsRouter, catsRouter]
for (var router of nestedRoutes) {
apiRouter.use(router.routes(), router.allowedMethods())
}
export default apiRouter;
routes/dogsRouter.js
import Router from 'koa-router'
const dogsRouter = new Router({ prefix: '/dogs' });
dogsRouter.get('/', async (ctx, next) => {
ctx.body = 'Dogs be here'
});
export default dogsRouter;
routes/catsRouter.js
import Router from 'koa-router'
const catsRouter = new Router({ prefix: '/cats' });
catsRouter.get('/', async (ctx, next) => {
ctx.body = 'Cats be here'
});
export default catsRouter;
您可以将所有路由放在一个名为 routes 的文件夹中,然后遍历该文件夹中的所有文件,需要它们并初始化。这样对于任何新路线,只需在路线文件夹中创建一个文件即可。
所以像这样:
index.js
const Koa = require("koa");
const logger = require("koa-logger");
const bodyParser = require("koa-bodyparser");
const app = new Koa();
app.use(logger());
app.use(bodyParser());
require("./routes")(app);
const server = app.listen(config.server.port);
module.exports = server;
/routes/index.js
const fs = require("fs");
const path = require("path");
const baseName = path.basename(module.filename);
const routes = fs
.readdirSync(path.join(__dirname))
.filter(
file =>
file.indexOf(".") !== 0 &&
file !== baseName &&
file.slice(-3) === ".js"
)
.map(file => require(path.join(__dirname, file)));
module.exports = function(app) {
for (var router of routes) {
app.use(router.routes());
}
};
然后在 /routes 文件夹中你会喜欢
/routes/user.js
/routes/customer.js
这些都是路由器出口,例如
/routes/auth.js
const Router = require("koa-router");
const authControllers = require("../controllers/auth");
const {
jwtAuth,
login,
register,
forgotPassword,
resetPassword,
getAuthenticatedUser
} = authControllers;
const router = new Router({ prefix: "/auth" });
router.post("/register", register);
router.post("/login", login);
router.post("/forgot-password", forgotPassword);
router.post("/reset-password/:resetToken", resetPassword);
router.get("/profile", jwtAuth, getAuthenticatedUser);
module.exports = router;
类似,但我真正需要的是:
app.js
"use strict";
import Koa from 'koa';
const app = new Koa();
import Router from 'koa-router';
const router = new Router();
import mount from 'koa-mount';
import routes from "./router/index.mjs";
app.use(mount(routes));
app.use(router.routes());
app.listen(3000, () => console.log("Listening on port: 3000"));
router/index.mjs
"use strict";
import Koa from 'koa';
const app = new Koa();
import Router from 'koa-router';
const router = new Router();
router.get('/', async (ctx, next) => {
ctx.body = {success: true};
await next();
});
app.use(router.routes());
export default app;