Bài 26-NodeJS RESTful Web Services – Phần 5


Như vậy là các Thím đã làm được HTTPGET (bài 23, bài 24) và HTTPPOST (bài 25). Tiếp tục WEB API cho NodeJS nha, ta mở lại Project ở bài 25 Để làm HTTPPUT. Cụ thể là viết API cho phép client gửi thông tin của một Product lên Server để CHỈNH SỬA Cơ sở dữ liệu MongoDB.

Để làm tốt HTTPPUT thì bắt buộc bạn phải hiểu HTTPPOST, vì cách thức lấy dữ liệu từ client lên Server là giống nhau, chỉ khác nhau ở chỗ tương tác Cơ sở dữ liệu, HTTPOST thì thêm mới còn HTTPPUT thì chỉnh sửa. Do đó Tui không giải thích thêm về cách thức lấy các biến trong bài này nữa nha, có gì coi lại bài HTTPPOST. Giờ Tui nhào luôn vào Coding nha:


/**
* '/editProduct' cho biết phía Client phải gọi: http://localhost:1337/editProduct
* và phải dùng HTTPPPUT (thấy hàm put không?)
*/
app.put('*/editProduct', 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 điều kiện chỉ tương tác trên Product có Ma là MaFromClient
var condition = { Ma: MaFromClient };
//Tạo đối tượng JSON đánh dấu chỉnh sửa thông qua từ khóa $set:
//(chỉnh sửa Tên, đơn giá) của Product có mã là MaFromClient
var editProduct = { $set: { Ten: TenFromClient, DonGia: DonGiaFromClient } };
//gọi lệnh updateOne để cập nhật
dbo.collection("Product").updateOne(condition, editProduct, function (err, obj) {
if (err) throw err;
console.log("1 document edited");
//kết thúc session thì đóng kết nối CSDL
db.close();
//kiểm tra xem cập nhật thành công hay không obj.result.n >0 là thành công
if (obj.result.n > 0)
result = "true"
//xuất thông báo cho Client biết là true(thành công), false(thất bại)
res.end(result)
});
});
})

Cuối cùng ta có coding của server.js tổng hợp như sau:


//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)
});
});
})
/**
* '/editProduct' cho biết phía Client phải gọi: http://localhost:1337/editProduct
* và phải dùng HTTPPPUT (thấy hàm put không?)
*/
app.put('*/editProduct', 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 điều kiện chỉ tương tác trên Product có Ma là MaFromClient
var condition = { Ma: MaFromClient };
//Tạo đối tượng JSON đánh dấu chỉnh sửa thông qua từ khóa $set:
//(chỉnh sửa Tên, đơn giá) của Product có mã là MaFromClient
var editProduct = { $set: { Ten: TenFromClient, DonGia: DonGiaFromClient } };
//gọi lệnh updateOne để cập nhật
dbo.collection("Product").updateOne(condition, editProduct, function (err, obj) {
if (err) throw err;
console.log("1 document edited");
//kết thúc session thì đóng kết nối CSDL
db.close();
//kiểm tra xem cập nhật thành công hay không obj.result.n >0 là thành công
if (obj.result.n > 0)
result = "true"
//xuất thông báo cho Client biết là true(thành công), false(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)

})

Nhấn F5 chạy lên, nếu cố gắng dùng trình duyệt để truy cập API editProduct http://localhost:1337/editProduct 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 editProduct mình dùng HTTPPUT.

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, chỉnh sửa lại Product có mã là P116 mà Tui cố tình nhập dữ liệu nó trùng với P115 ở bài 25:

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

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

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:

Dĩ nhiên ta cũng có thể xem trong PostMan:

Bạn thấy đó, Product có mã P116 đã được cập nhật thông tin thành công rồi nha.

Như vậy các bạn đã biết cách viết HTTPPUT để cập nhật dữ liệu cho Product trong 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 HTTPPUT chỉnh sửa Product tải ở đây.

Bài sau Tui sẽ hướng dẫn các Thím cách viết HTTPDELETE để xóa Product khỏi MongoDB. 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: http://communityuni.com/

Innovate Trading System (Kênh đầu tư lợi nhuận rất cao), các bạn nào quan tâm thì vào đây đầu tư nhé:

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

2 responses

  1. […] vậy là các Thím đã làm được HTTPGET (bài 23, bài 24) và HTTPPOST (bài 25), HTTPPUT(bài 26). Bây giờ ta qua Method phổ biến cuối cùng đó là HTTPDELETE dùng để viết các […]

  2. […] API này được deploy trong bài 28. Và API Edit Product được trình bày chi tiết trong bài 26. Nếu nếu các Thím có quên thì coi lại những bài này (tốt nhất là đừng quên, […]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: