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.
/** * '/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) }); }); })
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):
var bodyParser = require('body-parser'); app.use(bodyParser.json()); // support json encoded bodies app.use(bodyParser.urlencoded({ extended: true })); // support encoded bodies
Ta có Coding cuối cùng như sau cho server.js:
//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) })
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: 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!
[…] 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ụ […]
[…] 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 […]
[…] 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 […]