Tiếp nối bài viết về giới thiệu về REST, trong bài này chúng ta sẽ tạo RESTfull webservice và thiết kế API cho nó.Khiếp nghe vẻ to tát nhưng thực tế thì nó khá là đơn giản. 

Với Express server nó tạo ra mặc định tuần thủ hoàn toàn giao thức http đáp ứng gần hết các tiêu chí rồi o.0. Việc còn lại là thiết kế route hợp lý và tách lớp hệ thống. Thông thường khi lập trình web ta hay sử dụng mô hình MVC => Chia hệ thống thành Model - View - Controller. Với việc thiết kết API server thì phần view hiển thị không có. Lớp hiển thị của chúng ta là api. Chúng ta có thêm 1 lớp Model để kết nối xuống database và lớp controller , tập hợp các business logic. Tiếp đó với yêu cầu cache của hệ thống ta có thể đặt 1 thằng Redis để caching response nhưng trong bài này mình sẽ chưa đề cập đến nó.

Thay vì hùng hục bắt đầu code luôn phân tích chút đã. Yêu cầu của webservice là :

  • thiết kế API đơn giản, webservice tuân thủ REST, chỉ sử dụng 2 URL với mỗi tài nguyên.
  • Để toàn verb( hành vi với dữ liệu) ra ngoài URL.
  • Sử dụng đủ 4 thằng HTTP method POST, GET,PUT, DELETE để CRUD.
  • sử dụng tên gọi rõ ràng luôn tốt hơn là tóm lược ( ví dụ productName ta dung la proName chẳng hạn)

Hãy lập bảng nếu cần ví dụ :

Học lập trình trực tuyến cơ bản đến nâng cao

Tiếp theo hãy xây dựng dữ liệu mẫu bạn sẽ trả về dưới dạng JSON của từng trường hợp, xây dựng thành bảng status code và JSON khá tốt. Đảm bảo bạn luôn biết dữ liệu sau này sẽ ra sao.
{
    "name" : "Harry Potter và chiếc cốc lửa",
    "author" : "J.K. Rowling",
 .......
}

Tạo khung ứng dụng đơn giản.

Khởi tạo ứng dụng bằng cách tạo 1 thư mục , cd vào thư mục đó và tạo file package.json bằng cú pháp

    npm init

Cài đặt 1 số gói cần thiết nào

    npm i --save express body-parser

Tạo các thư mục đại diện cho các lớp. Ở đây mình không có phần view . Nên mình hệ thống này có cấu trúc đơn giản.

alt text

Tạo models cho service

\\models\book.js
data = {
    1: {
        name: "Harry Potter và chiếc cốc lửa",
        author: "J.K. Rowling"
    },
    2: {
        name: "Harry Potter và mệnh lệnh phượng hoàng",
        author: "J.K. Rowling"
    },
    3: {
        name: "Đau thương đến chết",
        author: "Quỷ cổ nữ"
    }
};

module.exports = data;

ở đây models của mình chỉ là 1 đối tượng hết sức đơn giản. Bình thường model cần phải là file mongoose để nối với MongoDB hoặc sử dụng cấu trúc của Sequelize để kết nối mySQL hoặc Postgres. Ở đây mình cũng sử dụng cú pháp khá nguy hiểm là tạo ra biến global

Tạo controller cho service

\\controllers\book.js
var books = {
    getAll: function(req, res) {
        var allbooks = data; 
        res.json(allbooks);
    },

    getOne: function(req, res) {
        var id = req.params.id;
        var book = data[0]; 
        res.json(book);
    },

    create: function(req, res) {
        var newbook = req.body;
        data.push(newbook);
        res.json(newbook);
    },

    update: function(req, res) {
        var updatebook = req.body;
        var id = req.params.id;
        data[id] = updatebook 
        res.json(updatebook);
    },

    delete: function(req, res) {
        var id = req.params.id;
        data.splice(id, 1) 
        res.json(true);
    }
};

module.exports = books;

ở đây các hàm của mình sẽ gọi đến thằng data lớp nằm ngay dưới nó.

Kết nối các mảnh ghép vào trong service

Tạo cái khung đã

\\app.js
var app = require("express")();
var bodyParser = require("body-parser");
var bookController = require("./controller/book");
var data = require("./models/book");

app.use(bodyParser.urlencoded());

app.route('/books')
    .get()
    .post()
    .put()
    .delete();

app.route('/books/:id')
    .get()
    .post()
    .put()
    .delete();

app.listen(3333)

Ở đây các bạn có thể thấy mình dùng hàm route của Express để định nghĩa URI, sau đó gán các method HTTP cho nó. Việc còn lại là đưa đúng controller vào từng vị trí mà thôi

var app = require("express")();
var bodyParser = require("body-parser");
var bookController = require("./controller/book");
var data = require("./models/book");

app.use(bodyParser.urlencoded());

app.route('/books')
    .get(bookController.getAll)
    .post(bookController.create)
    .put()
    .delete();

app.route('/books/:id')
    .get(bookController.getOne)
    .post()
    .put(bookController.update)
    .delete(bookController.delete);

app.listen(3333)

ở đây có mốt số cái còn thiếu các hàm xử lý thì bạn hãy xóa nó đi nhé, Ở nhà các bạn có thể viết thêm các logic này.

Việc còn lại là thử chạy service:

 node app.js

Vấn đề cần quan tâm với webservice

Tất nhiên ứng dụng trên còn thiếu phần rất quan trọng khi tạo web service đó là bảo mật. Hãy tưởng tượng đến việc đưa ứng dụng của bạn chạy thực tế mà ai cũng có thể post được vào server thì sao nhỉ ... Thảm họa. Trong bài viết sau mình sẽ đi sâu vào các giải pháp tăng khả năng bảo mật webservice