koa-router 入門與使用


koa-router

Koa 的路由中間件

使用方式

new Router([opts]);

創建一個路由.

選項參數:

  1. opts : Object
  2. opts.prefix : String - 設置路由的前綴
例子:

基本用法:

const Koa = require("Koa");
const Router = require("@koa/router");

// 初始化 koa 實例
const app = new Koa();

// 初始化路由實例
const router = new Router();

// 設置路由
router.get("/", ctx => {
  // ctx.router 可以訪問
  // 做一些當前路由的處理
});

// 注冊路由中間件
app.use(router.routes()).use(router.allowedMethods());
router.get|put|post|patch|delete|del => Router

創建 router 請求方法, 請求可以是上面的 get|put|post|patch|delete|del 之一, 比如 router.get()router.post()

路由請求中的第一個參數, 如 / 會和 URL 模式進行匹配, 如果匹配成功就掉對應的 回調函數控制器 對路由請求進行處理。

router.all() 會匹配所有的請求方法。

router
  .get("/", (ctx, next) => {
    ctx.body = "Hello,World";
  })
  .post("/users", (ctx, next) => {
    // ...
  })
  .put("/users/:id", (ctx, next) => {
    // ...
  })
  .del("/users/:id", (ctx, next) => {
    // ...
  })
  .all("/users/:id", (ctx, next) => {
    ctx.body = ctx.params;
  });

如果路徑匹配時, 它的路徑在 ctx._matchedRoute 可訪問, 如果命名, 則名稱在 ctx._matchedRouteName 中可用。

路由路徑將被轉換為正則表達式, 使用到的轉換庫是 path-to-regexp的規則。

匹配請求時暫時將不考慮查詢字符串。

命名路由

路由可以選擇有名稱。這允許生成 URL 並在開發過程中輕松重命名 URL, 方便在開發過程中使用和通過 ctx._matchedRouteName 來訪問當前路由器的名稱。

router.get("user", "/users/:id", ctx => {
  console.log(ctx._matchedRouteName); // user
  ctx.body = ctx.params;
});
多個中間件

可以給當前路由匹配, 提供多個中間件函數。

router.get(
  "/users/:id",
  async (ctx, next) => {
    if (ctx.params.id === "1") {
      await next();
    } else {
      ctx.status = 401;
      ctx.body = "無權訪問";
    }
  },
  ctx => {
    ctx.body = ctx.params;
  }
);

可以做一些權限校驗等, 這個路由內部 Layer 是橫向存儲中間件的。

嵌套路由

支持嵌套路由

// 論壇路由實例
const forums = new Router();
// 帖子路由實例
const posts = new Router();

posts.get("/", (ctx, next) => {
  ctx.body = ctx.request.url;
});

posts.get("/:pid", (ctx, next) => {
  ctx.body = {
    url: ctx.request.url,
    params: ctx.params
  };
});

// 注冊嵌套路由
forums.use("/forums/:fid/posts", posts.routes(), posts.allowedMethods());

// 注冊路由中間件
app.use(forums.routes());
路由器前綴

路由路徑可以在路由器級別加上前綴。

// 初始化路由實例
const router = new Router({
  prefix: "/users"
});

router.get("/", ctx => {
  ctx.body = ctx.url;
});

router.get("/:id", ctx => {
  ctx.body = ctx.params;
});

// 注冊路由中間件
app.use(router.routes()).use(router.allowedMethods());
URL 參數

動態路由會通過正則匹配到值后, 將作為 keyvalue 的形式添加到 ctx.params 屬性上。

router.get("/:category/:title", (ctx, next) => {
  console.log(ctx.params);
  // => { category: 'programming', title: 'how-to-node' }
});

path-to-regexp 模塊用於將路徑轉換成正則表達式。

router.routes() => Function

返回分配給與請求匹配的路由的路由器中間件。

router.use([path], middleware) => Router

使用給定的中間件

中間件按照 .use() 定義的順序運行。它們是按順序調用的, 請求從第一個中間件開始, 並按照中間件棧的方式工作。

// session 中間件會在 authorize 中間件之前執行
router.use(session()).use(authorize());

// 僅在給定路徑下使用中間件
router.use("/users", userAuth());

// 在 /users 或 /admin 路徑下調用 userAuth 中間件
router.use(["/users", "/admin"], userAuth());

app.use(router.routes());
router.prefix(prefix) => Router

為已經初始化的路由器實例設置路徑前綴

// 初始化路由實例
const router = new Router().prefix("/users");

router.get("/", ctx => {
  ctx.body = ctx.url;
});

router.get("/:id", ctx => {
  ctx.body = ctx.params;
});

// 注冊路由中間件
app.use(router.routes()).use(router.allowedMethods());
router.allowedMethods([options]) => Function

返回單獨的中間件函數, 用於處理響應選項請求, 其中包含允許的方法和運行的頭部字段。

例子
const Koa = require("koa");
const Router = require("@koa/router");

const app = new Koa();
const router = new Router();

app.use(router.routes());
app.use(router.allowedMethods());

或者

const Koa = require("koa");
const Router = require("@koa/router");
const Boom = require("boom");

const app = new Koa();
const router = new Router();

app.use(router.routes());
app.use(
  router.allowedMethods({
    throw: true,
    notImplemented: () => new Boom.notImplemented(),
    methodNotAllowed: () => new Boom.methodNotAllowed()
  })
);
router.redirect(source, destination, [code]) => Router

用可選的 30x 狀態代碼重定向 sourcedestination 路徑。

sourcedestination 都可以是路由名稱。

// 初始化路由實例
const router = new Router();

router.get("/", ctx => {
  ctx.body = "Hello";
});

router.get("about", "/about", ctx => {
  ctx.body = "重定向到了這里";
});

router.redirect("/user", "about");

// 注冊路由中間件
app.use(router.routes()).use(router.allowedMethods());
router.route(name) => Layer | false

通過名字搜索路由

// 初始化路由實例
const router = new Router();

router.get("/", ctx => {
  ctx.body = "Hello";
});

router.get("about", "/about", ctx => {
  ctx.body = "重定向到了這里";
});

router.redirect("/user", "about");

console.log(router.route("about"));

/**
 Layer {
  opts: {
    end: true,
    name: 'about',
    sensitive: false,
    strict: false,
    prefix: '',
    ignoreCaptures: undefined
  },
  name: 'about',
  methods: [ 'HEAD', 'GET' ],
  paramNames: [],
  stack: [ [Function] ],
  path: '/about',
  regexp: /^\/about(?:\/(?=$))?$/i { keys: [] }
}
 */
router.url(name, params, [options]) => String | Error

生成路由 URL, 獲取命名為 params 的路由名稱和地圖

router.get("user", "/users/:id", (ctx, next) => {
  // ...
});

router.url("user", 3);
// => "/users/3"

router.url("user", { id: 3 });
// => "/users/3"

router.use((ctx, next) => {
  // redirect to named route
  ctx.redirect(ctx.router.url("sign-in"));
});

router.url("user", { id: 3 }, { query: { limit: 1 } });
// => "/users/3?limit=1"

router.url("user", { id: 3 }, { query: "limit=1" });
// => "/users/3?limit=1"


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM