+2

[Nodejs] Koajs Bài 2: Routing trong Koajs

Như chúng ta đã biết, trừ những trang web chỉ có duy nhất một endpoint(một trang), thì Routing là một công việc tất yếu. Và đương nhiên, Routing cũng là một phần quan trọng trong Koajs, nhưng chức năng này lại không tích hợp sẵn trong Koa. Vì vậy hôm nay chúng ta sẽ tìm hiểu xem làm thế nào để phân trang trong Koa.js.

Phân trang thủ công

ảnh.png Dù nói là không tích hợp sẵn, nhưng Koajs hoàn toàn có những tính năng để chúng ta tự làm chức năng Routing. Dưới đây là một ví dụ đơn giản:

const Koa = require("koa");
const app = new Koa(); 

function getParams(href) {
    params = href.split('/').slice(3); //cắt params từ url, vì format url(http(s)://subdomain.secLevDomain.topLevDomain/param1/param2/...)
    //nên khi chúng ta split ra bằng "/" thì phần tử thứ 3 trở đi sẽ là params
    return params.filter((i) => i.length > 0); // lọc ra những phần tử trống rồi trả về
}

app.use(async (ctx, next) => {
    params = getParams(ctx.request.href); // gọi hàm lấy params
    if (params[0] == "xem") { //kiểm tra param đầu tiên
        if (params[1] == "san-pham") { //kiểm tra param thứ 2
            ctx.body = params[2]; //thay đổi body response(nội dung trả về) thành param thứ 3
        } else {
            await next(); //đi đến middleware tiếp theo
         }
    } else {
        await next(); //đi đến middleware tiếp theo
    }
});

app.use(async ctx => {
    ctx.body = "<h1>404</h1>"; // trả về trang 404
})

app.listen(3000); //chạy app ở port 3000

Kết quả: ảnh.png ảnh.png Nhìn vào đoạn code ở trên, ta thấy mọi thứ vẫn ổn, nhỉ? Tất nhiên là nếu chỉ đơn giản thì nó vẫn sử dụng được, nhưng rõ ràng là quá dài dòng và không hiệu quả. Nếu như cần đến param thứ 4, thứ 5 thì sẽ có rất nhiều if, else, khó debug(ta có thể lấy toàn bộ params thành một string, nhưng nếu như thế thì router phải theo một format nhất định, và ta cũng không thể dùng param động mà cần xử lí thêm). Dĩ nhiên ta có thể tối ưu nó bằng cách tách từng param là một middleware, nhưng nó vẫn chưa hiệu quả. Vì thế ta mới cần một thứ thần thánh, THƯ VIỆN.

Phân trang bằng thư viện

Một thư viện router được rất nhiều người sử với Koajs là koa-router. Cài đặt:

yarn add @koa/router
#hoặc
npm i @koa/router

Khởi tạo router:

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

Phân trang theo ví dự ở trên:

router.get('/xem/san-pham/:id', async (ctx, next) => {
    ctx.body = ctx.params.id;
});

Gắn vào app:


app.use(async (ctx, next) => {
    ctx.body = "<h1>404</h1>";
    await next();
});

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


//Ở đây 404 nằm ở trên vì nếu không match route koa-router sẽ không next(), cũng như không trả về gì
//Còn nếu ta next() trong middleware thì kq sẽ luôn là 404

Kết quả vẫn giống hệt như trên, nhưng code đã ngắn gọn và dễ hiểu hơn rất nhiều.

Ví dụ trong dự án KoaShop

Path của từng trang:

  • Trưng bày sản phẩm: /
  • Xem chi tiết sản phẩm: /view/:id
  • Trang tìm kiếm: /search
  • Admin: /admin
    Code:
const Koa = require("koa");
const app = new Koa();

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


router.get('/', ctx => ctx.body = "Home");
router.get('/view/:id', ctx => ctx.body = ctx.params.id);
router.get('/search', ctx => ctx.body = "Search");
router.get('/admin', ctx => ctx.body = "Admin");

app.use(async (ctx, next) => {
    ctx.body = "<h1>404</h1>";
    await next();
})

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

app.listen(3000, () => console.log("App is running"));

All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.