Tạo một webservice đơn giản với Express - Nodejs
nodejs
65
express
6
White

Quốc Cường viết ngày 02/11/2015

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ụ :
alt text

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

Bình luận


White
{{ comment.user.name }}
Bỏ hay Hay
{{comment.like_count}}
Male avatar
{{ comment_error }}
Hủy
   

Hiển thị thử

Chỉnh sửa

White

Quốc Cường

12 bài viết.
64 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}
Cùng một tác giả
White
29 6
Một câu hỏi thường gặp của lập trình viên có kinh nhiệm với SQL mới chuyển sang Mongo là làm thế nào để có thể model được quan hệ 1 : nhiều. Có rất...
Quốc Cường viết hơn 2 năm trước
29 6
White
24 7
Phát triển ứng dụng trên local tương đối đơn giản. Bạn chỉ việc cd vào thư mục , gõ câu lệnh node app.js , ứng dụng đã hoạt động. Mọi thứ sẽ trở n...
Quốc Cường viết hơn 2 năm trước
24 7
White
21 4
REST là kiến trúc phần mềm phổ biến nhất hiện nay trên internet. Thực tế khi đọc bài viết về REST các bạn sẽ thấy nó hơi bị mơ hồ khó hiểu. REST ...
Quốc Cường viết hơn 2 năm trước
21 4
Bài viết liên quan
White
0 0
Lâu lâu không động vào nodejs không biết mấy ông tool tiếc này đi đâu về đâu rồi. Trước đây thì mình vẫn có thể dùng istanbul với mocha đơn giản th...
Hoàng Duy viết hơn 1 năm trước
0 0
White
1 0
Xử lý đồng bộ một mảng bằng Promise thay cho async.eachSeries Tựa Đang muốn chạy một hàm trong đó xử lý đồng bộ từng phần tử trong một mảng, do g...
Cuong Pham viết hơn 1 năm trước
1 0
{{like_count}}

kipalog

{{ comment_count }}

bình luận

{{liked ? "Đã kipalog" : "Kipalog"}}


White
{{userFollowed ? 'Following' : 'Follow'}}
12 bài viết.
64 người follow

 Đầu mục bài viết

Vẫn còn nữa! x

Kipalog vẫn còn rất nhiều bài viết hay và chủ đề thú vị chờ bạn khám phá!