Hapi.js framework, tìm hiểu về routing trong hapi.js

1. Định nghĩa

Routing trong hapi.js giúp server phân loại và xử lý các tác vụ theo yêu cầu được gửi lên từ người dùng. Trong hapi, routing được khai báo như là một thuộc tính của server server.route(...).

2. Các thuộc tính cơ bản

Khi định nghĩa một route trong hapi, các bạn cần ba thuộc tính cơ bản: path, methodhandler. Các thuộc tính này được khai báo dưới dạng một đối tượng đơn giản như sau:

server.route({
    method: 'GET',
    path: '/',
    handler: function (request, h) {
        return 'Hello World!';
    }
});

# Method

Khi một request được gửi lên server, nó sẽ được gửi theo nhiều phương thức HTTP khác nhau. Để hapi biết cần xử lý request đó ở route nào, chúng ta cần khai báo thuộc tính method trong mỗi route. Method có thể nhận một hoặc nhiều phương thức HTTP hợp lệ.

Ví dụ: Chúng ta muốn trả về cùng một kết quả khi người dùng gửi request lên theo hai phương thức POSTPUT như sau:

server.route({
    method: ['PUT', 'POST'],
    path: '/',
    handler: function (request, h) {
        return 'I did something!';
    }
});

# Path

Path là một chuỗi, được hiểu là đường dẫn phía sau domain khi chúng ta nhập vào url của trình duyệt.

Ví dụ: Chúng ta muốn khi truy cập vào url http://localhost/hello thì sẽ nhận được một chuỗi Hello World!. Vậy path của route này sẽ là /hello.

server.route({
    method: 'GET',
    path: '/hello',
    handler: function (request, h) {
        return 'Hello World!';
    }
});

# Parameters

Chúng ta có thể thêm các tham số (parameters) vào route bằng cách đặt tên tham số trong dấu {}.

server.route({
    method: 'GET',
    path: '/hello/{user}',
    handler: function (request, h) {
        return 'Hello ' + request.params.user;
    }
});

Với các tham số được truyền vào, nó sẽ được truy vấn qua đối tượng request.params. Chúng ta có thể định nghĩa nhiều tham số trong một route. Mỗi tham số phải được ngăn cách nhau bởi một ký tự hợp lệ trong url.

  • /path/{param1}/{param2}
  • /path/{param1}.{param2}
  • /path/{param1}-{param2}

# Optional parameters

Để định nghĩa một tham số không bắt buộc, chỉ cần thêm dấu ? vào cuối tên của tham số. Lúc này, tham số có thể có hoặc không có giá trị.

server.route({
    method: 'GET',
    path: '/hello/{user?}',
    handler: function (request, h) {
        const user = request.params.user ? request.params.user : 'stranger';
        return `Hello ${user}!`;
    }
});

# Query Parameters

Query parameters là một cách phổ biến để gửi dữ liệu lên server. Các tham số được gửi qua URL dưới dạng key = value. Ví dụ:

localhost:3000?name=ferris&location=chicago

Trong route của hapi các bạn không cần phải khai báo thêm gì. Toàn bộ các query parameters được truy vấn thông qua đối tượng request.query.

server.route({
    method: 'GET',
    path: '/',
    handler: function (request, h) {
        return `Hello ${request.query.name}!`;
    }
});

# Request Payload

Request payload được hiểu là một khối dữ liệu được truyền lên server thông qua các phương thức ẩn như POST, PATCH hoặc PUT, …

Dữ liệu kiểu này được truy vấn qua đối tượng request.payload.

server.route({
    method: 'POST',
    path: '/signup',
    handler: function (request, h) {
        const payload = request.payload;
        return `Welcome ${encodeURIComponent(payload.username)}!`;
    }
});

# Handler

Handler là một hàm có nhiệm vụ xử lý và trả về kết quả cho mỗi route. Handler có hai tham số chính là requesth. Hàm này có thể trả về một giá trị, một promise hoặc throw một lỗi.

Tham số request là một đối tượng chứa các thông tin của một request từ người dùng, chẳng hạn như đường dẫn, các dữ liệu payload, thông tin xác thực người dùng, header, v.v. Bạn có thể tham khảo thêm tại đây: https://hapijs.com/api#request

Tham số thứ hai h là một đối tượng chứa các phương thức bổ sung, hỗ trợ cho việc trả về kết quả của handler. Chúng ta có thể chỉ định các giá trị được trả về như http status code, headers, content type, content length, v.v.

server.route({
    method: 'GET',
    path: '/',
    handler: function (request, h) {
        return h.response('created').code(201);
    }
});

Đoạn mã trên sẽ trả về http status code là 201 cho phía người dùng. Tham khảo thêm tại đây: https://hapijs.com/api#response-toolkit

# Options

Ngoài ba thuộc tính cơ bản kể trên, bạn có thể khai báo thêm một thuộc tính options cho mỗi route. Thuộc tính này bao gồm các cấu hình cho validation, authentication, caching, v.v. Xem thêm tại đây: https://hapijs.com/api#route-options

server.route({
    method: 'POST',
    path: '/signup',
    handler: function (request, h) {
        const payload = request.payload;
        return `Welcome ${encodeURIComponent(payload.username)}!`;
    },
    options: {
        auth: false,
        validate: {
            payload: {
                username: Joi.string().min(1).max(20),
                password: Joi.string().min(7)
            }
        }
    }
});

Đoạn code trên có hai tùy chọn là authvalidate.

auth dùng để cấu hình xác thực người dùng cho route. Tuy nhiên bạn thấy, route này có nhiệm vụ để đăng ký một tài khoản mới nên không cần có xác thực người dùng, do đó, tùy chọn auth sẽ là false.

validate cho phép bạn đặt các quy tắc để xác thực các thành phần như headers, params, payloadfailAction. Bạn có thể sử dụng thư viện Joi để validate cho payload.

3. Xử lý lỗi 404 đơn giản

Đôi khi sẽ có những người dùng cố gắng hoặc vô tình truy cập vào một đường dẫn không có sẵn. Để thông báo với người dùng rằng họ đang gặp phải lỗi không tìm thấy tài nguyên hoặc không có phương thức nào để xử lý request là trả về một lỗi 404. Trong hapi, cách đơn giản nhất là tạo một route chấp nhận tất cả các method, tất cả các path và nằm cuối cùng trong danh sách các route được khai báo.

server.route({
    method: '*',
    path: '/{any*}',
    handler: function (request, h) {
        return '404 Error! Page Not Found!';
    }
});

Bạn có thể dùng dấu * để gán cho method, điều này có nghĩa route này đang chấp nhận tất cả các phương thức của request. Sau đó gán chuỗi /{any*} cho path, như vậy route này sẽ được thực thi khi không có bất kỳ route nào map với đường dẫn mà người dùng truy cập. Cuối cùng là trả về chuỗi 404 Error! Page Not Found! tại hàm xử lý handler.

4. Lời kết

Qua bài viết này, bạn sẽ nắm được các thuộc tính cơ bản, khái quát về cách sử dụng routing trong hapi.js. Hi vọng bạn sẽ thấy thích nó và tiếp tục theo dõi những bài viết tiếp theo trong series về hapi.js. Cảm ơn các bạn đã dành thời gian cho bài viết này!

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *