Bài 25-NodeJS RESTful Web Services – Phần 4

Tiếp tục WEB API cho NodeJS nha, ta mở lại Project ở bài 24. Để làm HTTPOST, cụ thể là viết API cho phép client gửi thông tin của một Product lên Server để thêm mới vào Cơ sở dữ liệu MongoDB.

HTTPPOST nó hơi phức tạp 1 xíu, nó có nhiều content-type khác nhau để gửi và nhận dữ liệu như là multipart/form-data, hay application/x-www-form-urlencoded hay raw….Tương ứng với mỗi content-type đó sẽ có cách bóc tách lấy dữ liệu khác nhau. Tui không đủ thời gian để nói hết các loại content-type, nên trong bài học này Tui sẽ hướng dẫn các bạn làm 1 cái thôi, đó là application/x-www-form-urlencoded.

Tui nói lại Cơ sở dữ liệu QuanLySanPham 1 xíu, đó là cấu trúc của bảng Product. Nó có Ma, Ten, DonGia. Tức là ở Client phải gửi chính xác 3 biến này và đủ 3 giá trị này lên cho Server thông qua Web API RESTful, ở trên Server sẽ nhận 3 thông số này (dĩ nhiên có một số Anh Hùng Xạ Điêu không thích đều này, họ không cần quy tắc nào cả, đặt tên sao cũng được, miễn truy lùng ra đúng giá trị cần nhập->Không nên tỏ vẻ nguy hiểm chỗ này nha vì nó chả làm các Thím đẹp trai ra 1 lạng nào cả mà làm cho trán của các Thím thêm mấy nếp nhăn vì phải suy nghĩ nhiều, đặc biệt khi làm việc nhóm thì các thành viên khác khóc ròng vì không thể biết được biến đó tương ứng với các thông số nào).

OK, quay trở lại server.js, ta bổ sung coding sau để tạo API cho phép Lưu mới một Product.

[code language=”javascript”]

/**
* ‘/addProduct’ cho biết phía Client phải gọi: http://localhost:1337/addProduct
* và phải dùng HTTPPOST (thấy hàm post không?)
*/
app.post(‘*/addProduct’, function (req, res) {
//định dạng content-type là application/x-www-form-urlencoded
res.writeHead(200, { ‘Content-Type’: ‘application/x-www-form-urlencoded;charset=utf-8’ });
//Khi định dạng content-type là application/x-www-form-urlencoded
//thì để truy suất tới các biến từ Client gửi lên ta làm như sau:
//Lấy đối tượng body trong req.body rồi req.body.[các biến từ client]
//[các biến từ client] là do lập trình viên quy định
//ta nên đặt tên biến trùng khớp với các cột trong các Bảng mà ta muốn thêm mới
//để tránh việc nhầm lẫn cũng như giúp cho các lập trình viên khác và ta dễ đọc
var MaFromClient = req.body.Ma
var TenFromClient = req.body.Ten
var DonGiaFromClient = req.body.DonGia
var result = “false”
MongoClient.connect(url, function (err, db) {
if (err) throw err;
//kết nối cơ sở dữ liệu QuanLySanpham
var dbo = db.db(“QuanLySanPham”);
//Tạo 1 JsonObject để lưu mới, cú pháp: { Ma: MaFromClient, Ten: TenFromClient, DonGia: DonGiaFromClient }
//Lưu ý Ma, Ten, DonGia ở bên trái dấu hai chấm (:) phải chính xác với tên cột được khái báo trong bảng
var newProduct = { Ma: MaFromClient, Ten: TenFromClient, DonGia: DonGiaFromClient };
//Gọi hàm insertOne để thêm mới 1 Product
dbo.collection(“Product”).insertOne(newProduct, function (err, obj) {
if (err) throw err;
console.log(“1 document inserted”);
//kết thúc session thì đóng kết nối CSDL
db.close();
//Kiểm tra xem obj.result.n ta sẽ biết bao nhiêu Record được thêm mới
//rõ ràng nếu >0 tức là có record được thêm mới
if (obj.result.n > 0)
result = “true”
//xuất ra cho Client biết là true hay false, dựa vào kết quả này mà Client sẽ
//hiển thị thêm mới Product thành công hay thất bại
res.end(result)
});
});
})

[/code]

Lưu ý, để NodeJS có thể hiểu được thì ta phải thêm các thư viện sau ở những dòng đầu ngay sau khi khai báo đối tượng app của file server.js (thiếu 3 dòng này là không làm được cơm phở gì đâu nha):

[code language=”javascript”]

var bodyParser = require(‘body-parser’);
app.use(bodyParser.json()); // support json encoded bodies
app.use(bodyParser.urlencoded({ extended: true })); // support encoded bodies

[/code]

Ta có Coding cuối cùng như sau cho server.js:

[code language=”javascript”]

//gọi thư viện express
var express = require(‘express’);
//tạo đối tượng có kiểu express()
var app = express();
//gọi thư viện fs
var fs = require(“fs”);
//khai báo PORT mặc định khi chạy(từ hệ thống, nó có PORT nào thì lấy PORT đó)
var port = process.env.PORT;
//chuỗi kết nối tới Cơ sở dữ liệu MongoDB
var url = “mongodb://localhost:27017/”;
//Gọi thư viện mongoDB và khởi tạo đối tượng cho nó
var MongoClient = require(‘mongodb’).MongoClient;
var bodyParser = require(‘body-parser’);
app.use(bodyParser.json()); // support json encoded bodies
app.use(bodyParser.urlencoded({ extended: true })); // support encoded bodies
/**
* Coding tạo HTTPGET lấy toàn bộ danh sách sản phẩm
* ‘/products’ có nghĩa là URI để lấy toàn bộ sản phẩm
* ta thích đặt gì cũng được, tuy nhiên vì danh sách nên có số nhiều là s (hoặc có chữ list cho dễ phân biệt)
* chẳng hạn như: http://localhost:1337/products
*/
app.get(‘*/products’, function (req, res) {
//thiết lập lấy dữ liệu với UTF-8
res.writeHead(200, { ‘Content-Type’: ‘text/json; charset=utf-8’ });
MongoClient.connect(url, function (err, db) {
if (err) throw err;
//kết nối Cơ sở dữ liệu MongoDB tên là QuanLySanPham
var dbo = db.db(“QuanLySanPham”);
//truy vấn toàn bộ dữ liệu trong bảng Product:
dbo.collection(“Product”).find({}).toArray(function (err, result) {
if (err) throw err;
console.log(result);
//đưa về JSON
var s = JSON.stringify(result);
//xuất ra Client:
res.end(s);
//đóng kết nối CSDL khi xong session
db.close();
});
});
})
/**
*
* coding tạo API lấy chi tiết Product
* Cú pháp: ‘/products/:id’
* =>URI khi chạy: http://localhost:1337/products/P1 để lấy Product có mã là P1
* Ngoài ra bạn có thể ‘/:id’
* =>URI khi chạy: http://localhost:1337/P1
* Tuy nhiên ta nên cho phân cấp như trong ví dụ này để biết rằng nó thuộc nhóm products
* http://localhost:1337/products/P1 sẽ dễ hiểu hơn
*/
app.get(‘*/products/:id’, function (req, res) {
//lấy được giá trị truyền vào từ URI:
var MaTim = req.params.id
res.writeHead(200, { ‘Content-Type’: ‘text/json; charset=utf-8’ });
MongoClient.connect(url, function (err, db) {
if (err) throw err;
//tạo điều kiện lọc theo Mã
//nó có cú pháp là 1 Json { Ma: MaTim } thì Ma là tên cột, MaTim là giá trị ta muốn lọc
//MaTim lâsy từ req.params.id
var query = { Ma: MaTim }
//Kết nối Cơ sở dữ liệu QuanLySanPham
var dbo = db.db(“QuanLySanPham”);
//truy vấn dữ liệu từ bảng Product và lọc theo MaTim
dbo.collection(“Product”).findOne(query, function (err, result) {
if (err) throw err;
console.log(result);
//đưa dữ liệu lấy được về JSON
var s = JSON.stringify(result);
//xuất ra client
res.end(s);
//xong session thì đóng kết nối
db.close();
});
});
})
/**
* ‘/addProduct’ cho biết phía Client phải gọi: http://localhost:1337/addProduct
* và phải dùng HTTPPOST (thấy hàm post không?)
*/
app.post(‘*/addProduct’, function (req, res) {
//định dạng content-type là application/x-www-form-urlencoded
res.writeHead(200, { ‘Content-Type’: ‘application/x-www-form-urlencoded;charset=utf-8’ });
//Khi định dạng content-type là application/x-www-form-urlencoded
//thì để truy suất tới các biến từ Client gửi lên ta làm như sau:
//Lấy đối tượng body trong req.body rồi req.body.[các biến từ client]
//[các biến từ client] là do lập trình viên quy định
//ta nên đặt tên biến trùng khớp với các cột trong các Bảng mà ta muốn thêm mới
//để tránh việc nhầm lẫn cũng như giúp cho các lập trình viên khác và ta dễ đọc
var MaFromClient = req.body.Ma
var TenFromClient = req.body.Ten
var DonGiaFromClient = req.body.DonGia
var result = “false”
MongoClient.connect(url, function (err, db) {
if (err) throw err;
//kết nối cơ sở dữ liệu QuanLySanpham
var dbo = db.db(“QuanLySanPham”);
//Tạo 1 JsonObject để lưu mới, cú pháp: { Ma: MaFromClient, Ten: TenFromClient, DonGia: DonGiaFromClient }
//Lưu ý Ma, Ten, DonGia ở bên trái dấu hai chấm (:) phải chính xác với tên cột được khái báo trong bảng
var newProduct = { Ma: MaFromClient, Ten: TenFromClient, DonGia: DonGiaFromClient };
//Gọi hàm insertOne để thêm mới 1 Product
dbo.collection(“Product”).insertOne(newProduct, function (err, obj) {
if (err) throw err;
console.log(“1 document inserted”);
//kết thúc session thì đóng kết nối CSDL
db.close();
//Kiểm tra xem obj.result.n ta sẽ biết bao nhiêu Record được thêm mới
//rõ ràng nếu >0 tức là có record được thêm mới
if (obj.result.n > 0)
result = “true”
//xuất ra cho Client biết là true hay false, dựa vào kết quả này mà Client sẽ
//hiển thị thêm mới Product thành công hay thất bại
res.end(result)
});
});
})
/**
* Chạy Server
*/
var server = app.listen(port, function () {

var host = server.address().address
var port = server.address().port

console.log(“Example app listening at http://%s:%s”, host, port)

})

[/code]

Nhấn F5 chạy lên, nếu cố gắng dùng trình duyệt để truy cập API addProduct http://localhost:1337/addProduct ta sẽ thấy lỗi như thế này:

dĩ nhiên là lỗi rồi, vì cách chạy trình duyệt đó chỉ thường áp dụng cho các HTTPGET mà thôi. Trong khi addProduct mình dùng HTTPPOST.

Vậy làm sao để chạy nó ta? đó là dùng các công cụ REST client như PostMan (Chrome), HTTP Requester (Firefox), WCF client Test (Microsoft). Lưu ý các công cụ này ta vẫn Debug được NodeJS một cách trực tiếp trong Visual nha (xem lại bài này để biết cách  Debug->Kéo xuống cuối bài hướng dẫn sẽ thấy).

OK, bây giờ Thím mở PostMan lên:

Mục 1: Chọn POST (vì addProduct viết theo method POST)

Mục 2: Nhập URI http://localhost:1337/addProduct

Mục 3: Chọn body và checked vào x-www-form-urlencoded

Mục 4: Nhập các Parameter trong body cho API. Lưu ý nhập chính xác tên biến khớp tới Cột trong bảng CSDL nha. Tui chụp hình dưới đây để các bạn hiểu về sự so khớp từ Client -> API

Mục 5: Bấm SEND

Mục 6: Kết quả cho biết là true hay false (true thành công, false thất bại.

Bây giờ ta có thể chạy lại API http://localhost:1337/products để xem được kết quả có thêm thành công hay chưa:

Bạn thấy đó, Tui mới bấm thêm đại 2 Product và thấy nó lưu thành công vào Cơ sở dữ liệu.

Như vậy các bạn đã biết cách viết HTTPPOST để lưu một Product vào cơ sở dữ liệu MongoDB như thế nào rồi nha.

Lưu ý muốn Debug để gỡ lỗi từng bước thì xem lại bài 23, kéo xuống dưới cùng có hướng dẫn

Source code HTTPPOST Thêm mới Product tải ở đây.

Bài sau Tui sẽ hướng dẫn các Thím cách viết HTTPPUT để chỉnh sửa dữ liệu, và sau đó là HTTPDELETE. Các bạn chú ý theo dõi nhé

Các khóa học online khác, bạn có thể tham khảo tại đây:

https://unica.vn/?aff=11929

Chúc các bạn thành công!

2 thoughts on “Bài 25-NodeJS RESTful Web Services – Phần 4”

Leave a Reply