Bài 69: Xây dựng Web Service dùng API RESTful Service(phần 2)


Trong bài này Tui sẽ hướng dẫn chi tiết cách tạo Web API (lý thuyết ở đây), cách cấu hình IIS, cách sử dụng công cụ Postman(với những ai dùng chrome), cách sử dụng HttpRequester (với những ai dùng Firefox). PostmanHttpRequester là một trong những công cụ hiệu quả nhất để TEST coding của ta, nếu code của ta pass qua được công cụ này thì có thể kết luận rằng Webservice của ta chắc chắn hoạt động tốt.

Để cho có cảm giác Tui sẽ tạo một cơ sở dữ liệu SQL Server, WebAPI sẽ tương tác dữ liệu này bằng cách sử dụng LinQ to SQL:

Bước 1: Tạo cơ sở dữ liệu tên “dbFood”, có một bảng “Food” gồm 4 cột (id để auto) như dưới đây:

h69-0Các bạn có thể tải SQL Script ở đây để tạo CSDL cho lẹ: http://www.mediafire.com/download/48dkwoqka2e1w07/dbFood.sql

Bước 2: Tiến hành viết Web API

Để tạo Project sử dụng Web API có nhiều cách tạo, ở đây Tui sử dụng cách đơn giản nhất để các bạn bớt rối.

Từ Visual Studio 2013 vào menu File/chọn new/ chọn Project:

h69-1Sau khi chọn Project, màn hình sau xuất hiện:

h69-2Chọn các cấu hình như trên, đặt tên Project là “FoodServer” rồi nhấn OK.

Project mặc định ban đầu như sau:

h69-3Giờ ta tiến hành tạo LinQ to SQL cho CSDL dbFood để dễ xử lý như sau:

Bấm chuột phải vào Project/ chọn :

h69-4Màn hình tạo tên LINQ to SQL hiển thị lên, ta tạo tên rồi nhấn OK:

h69-5(chú ý đôi khi bạn sẽ không thấy LINQ to SQL Classes ở màn hình này), nếu không thấy thì chọn New Item:

h69-6Ta chọn các mục giống như bên dưới, tìm tới LINQ to SQL Classes rồi đặt tên DBFood tương tự như trên:

h69-7Cả 2 cách cuối cùng cũng trạo được DBFood LINQ như sau:

h69-8– Ta tiến hành cấu hình để kéo Cơ sở dữ liệu vào làm các lớp tương tác:

Bạ mở Server Explorer (vào menu View/Server Explorer), bấm chọn theo các bước như bên dưới (lệ thuộc vào Server của bạn mà chọn Server name, User đăng nhập cho phù hợp):

h69-9Khi khi bấm OK, bạn sẽ thấy Server Explorer có thêm mục sau:

h69-10Bạn kéo thả bảng Food vào mục bên phải như hình trên.

Tiếp theo bạn tạo 1 thư mục (tên gì cũng được), ở đây Tui đặt đại tên Controllers (bấm chuột phải vào Project/chọn Add/chọn New Folder):

h69-11Sau khi thư mục Controllers được tạo ra, bạn bấm chuột phải vào Thư Mục này rồi chọn Add/Controller..:

h69-12Sau khi bạn chọn Controller… màn hình sau xuất hiện:

h69-13Ta chọn Web API 2 Controller – Empty rồi bấm Add, Visual sẽ hiển thị màn hình đặt tên cho Controller:

h69-14Mặc định là chữ Default, bây giờ bạn đổi lại thành Food (thường ta làm API cho bảng nào thì lấy tên bảng đó), đó là lý do vì sao Tui đặt là Food:

h69-15Tập tin FoodController.cs sẽ được tạo ra, nhưng ta chỉ lấy Food(bỏ chữ Controller đằng sau đi) để tương tác (đây là cơ chế hoạt động). Ta xem cấu trúc Controller được tạo ra:

h69-16Cấu trúc có gì?

  • File WebApiConfig.cs được sinh ra trong thư mục App_Start, bạn để ý  routeTemplate: “api/{controller}/{id}”, tức là khi ta dùng thì viết: “api/food” để lấy toàn bộ danh sách, hay “api/food/3” để lấy chi tiết  1 Food có mã là 3.
  • File FoodController.cs kế thừa từ ApiController

Bây giờ ta tiến hành viết các chức năng (viết trong file FoodController.cs) :

  • HttpGet: Truy vấn thông tin
  • HttpPost: Thêm mới thông tin
  • HttpPut: Thay đổi thông tin
  • HttpDelete: Xóa thông tin

Trước tiên ta làm HttpGet:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;

namespace FoodServer.Controllers
{
public class FoodController : ApiController
{
///

<summary>
/// Dịch vụ lấy toàn bộ Food
/// </summary>


/// <returns></returns>
[HttpGet]
public List<Food> GetFoodLists()
{
DBFoodDataContext db = new DBFoodDataContext();
return db.Foods.ToList();
}
///

<summary>
/// Dịch vụ lấy 1 Food theo khóa chính nào đó
/// </summary>


/// <param name="id"></param>
/// <returns></returns>
[HttpGet]
public Food GetFood(int id)
{
DBFoodDataContext db = new DBFoodDataContext();
return db.Foods.FirstOrDefault(x => x.id == id);
}
}
}

Chú ý là Web API nó không quan tâm tới tên phương thức (viết tên gì cũng được, nó tự động lấy chính xác Service yêu cầu), (không cho phép trùng tên biến). Ví dụ nếu bạn cố tình tạo thêm 1 hàm:


[HttpGet]
public Food GetFood_test(int id)
{
DBFoodDataContext db = new DBFoodDataContext();
return db.Foods.FirstOrDefault(x => x.id == id);
}

Khi chạy sẽ báo lỗi ngày (vì hệ thống không quan tâm tên hàm), nó thấy 2 biến id giống nhau ở trên 2 hàm nó sẽ không biết dùng cái nào (vì chúng cùng nhóm HttpGet). Cụ thể là lỗi sau:

Multiple actions were found that match the request:
GetFood on type FoodServer.Controllers.FoodController
GetFood_test on type FoodServer.Controllers.FoodController

Tiếp theo ta viết HttpPost (thêm mới):


///

<summary>
/// Dịch vụ này để thêm mới 1 Food, các thông số gửi từ client lên
/// </summary>


/// <param name="name">tên </param>
/// <param name="type">loại-nhóm</param>
/// <param name="price">đơn giá</param>
/// <returns>true thành công, false thất bại</returns>
[HttpPost]
public bool InsertNewFood(string name,string type,int price)
{
try
{
DBFoodDataContext db = new DBFoodDataContext();
Food food = new Food();
food.name = name;
food.type = type;
food.price = price;
db.Foods.InsertOnSubmit(food);
db.SubmitChanges();
return true;
}
catch
{
return false;
}
}

Để chỉnh sửa thông tin ta viết HttpPut:


///

<summary>
/// Dịch vụ chỉnh sửa thông tin
/// </summary>


/// <param name="id">mã food muốn sửa</param>
/// <param name="name">tên mới</param>
/// <param name="type">loại mới</param>
/// <param name="price">giá mới</param>
/// <returns></returns>
[HttpPut]
public bool UpdateFood(int id,string name,string type,int price)
{
try
{
DBFoodDataContext db = new DBFoodDataContext();
//lấy food tồn tại ra
Food food = db.Foods.FirstOrDefault(x=>x.id==id);
if (food == null) return false;//không tồn tại false
food.name = name;
food.type = type;
food.price = price;
db.SubmitChanges();//xác nhận chỉnh sửa
return true;
}
catch
{
return false;
}
}

Cuối cùng để xóa 1 Food ta viết HttpDelete như sau:


///

<summary>
/// Dịch vụ dùng để xóa Food có id
/// </summary>


/// <param name="id">id muốn xóa</param>
/// <returns></returns>
[HttpDelete]
public bool DeleteFood(int id)
{
DBFoodDataContext db = new DBFoodDataContext();
//lấy food tồn tại ra
Food food = db.Foods.FirstOrDefault(x => x.id == id);
if (food == null) return false;
db.Foods.DeleteOnSubmit(food);
db.SubmitChanges();
return true;
}

Sau cùng ta có coding tổng hợp của FoodController như sau:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;

namespace FoodServer.Controllers
{
public class FoodController : ApiController
{
///

<summary>
/// Dịch vụ lấy toàn bộ Food
/// </summary>


/// <returns></returns>
[HttpGet]
public List<Food> GetFoodLists()
{
DBFoodDataContext db = new DBFoodDataContext();
return db.Foods.ToList();
}
///

<summary>
/// Dịch vụ lấy 1 Food theo khóa chính nào đó
/// </summary>


/// <param name="id"></param>
/// <returns></returns>
[HttpGet]
public Food GetFood(int id)
{
DBFoodDataContext db = new DBFoodDataContext();
return db.Foods.FirstOrDefault(x => x.id == id);
}
///

<summary>
/// Dịch vụ này để thêm mới 1 Food, các thông số gửi từ client lên
/// </summary>


/// <param name="name">tên </param>
/// <param name="type">loại-nhóm</param>
/// <param name="price">đơn giá</param>
/// <returns>true thành công, false thất bại</returns>
[HttpPost]
public bool InsertNewFood(string name,string type,int price)
{
try
{
DBFoodDataContext db = new DBFoodDataContext();
Food food = new Food();
food.name = name;
food.type = type;
food.price = price;
db.Foods.InsertOnSubmit(food);
db.SubmitChanges();
return true;
}
catch
{
return false;
}
}
///

<summary>
/// Dịch vụ chỉnh sửa thông tin
/// </summary>


/// <param name="id">mã food muốn sửa</param>
/// <param name="name">tên mới</param>
/// <param name="type">loại mới</param>
/// <param name="price">giá mới</param>
/// <returns></returns>
[HttpPut]
public bool UpdateFood(int id,string name,string type,int price)
{
try
{
DBFoodDataContext db = new DBFoodDataContext();
//lấy food tồn tại ra
Food food = db.Foods.FirstOrDefault(x=>x.id==id);
if (food == null) return false;//không tồn tại false
food.name = name;
food.type = type;
food.price = price;
db.SubmitChanges();//xác nhận chỉnh sửa
return true;
}
catch
{
return false;
}
}
///

<summary>
/// Dịch vụ dùng để xóa Food có id
/// </summary>


/// <param name="id">id muốn xóa</param>
/// <returns></returns>
[HttpDelete]
public bool DeleteFood(int id)
{
DBFoodDataContext db = new DBFoodDataContext();
//lấy food tồn tại ra
Food food = db.Foods.FirstOrDefault(x => x.id == id);
if (food == null) return false;
db.Foods.DeleteOnSubmit(food);
db.SubmitChanges();
return true;
}
}
}

Bây giờ ta tiến hành cấu hình Port để test trên IIS express hoặc bạn cấu hình IIS full. Trong bài này Tui hướng dẫn cách sử dụng IIS Express.

Bạn bấm chuột phải vào FoodServer Project/ chọn Properties:

h69-17Tại màn hình Properties / chọn mục Web:

h69-18Bạn cấu hình như trên, Port tui chỉnh là 8888, bạn chọn Port nào cũng được, nhưng thường là 4 chữ số.

Sau đó bấm Create Virtual Directory:

h69-19Nếu Visual thông báo màn hình trên coi như bạn thành công.

Bây giờ ta thử chức năng HttpGet để lấy toàn bộ Food và lấy 1 Food theo id bất kỳ:

F5 để chạy Project:

h69-20Bạn chỉnh lại: http://localhost:8888/api/food để lấy toàn bộ Food:

h69-21Để lấy 1 Food có mã bất kỳ:

Ví dụ: Lấy Food có mã id=15: http://localhost:8888/api/food/15

h69-22Hoặc: http://localhost:8888/api/food?id=15

h69-23Ta cần phải biết các công cụ để test HttpGet,HttpPost,HttpPutHttpDelete.

Bài kế tiếp Tui sẽ hướng dẫn cách dùng công cụ Postman và HttpRequester để xử lý 4 tác vụ trên.

Bây giờ các bạn hãy làm theo hướng dẫn này để có thể tạo được 1 Web API hoàn chỉnh, test trước phần HttpGet mà Tui đã trình bày ở trên trước.

Các bạn tải source code FoodServer ở đây: http://www.mediafire.com/download/c24sm4hg19v8grz/FoodServer.rar

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

9 responses

  1. […] HttpRequester (firefox addon) và Postman (chrome addon) . Các bạn cần nắm rõ bài 68 và bài 69 để hiểu và triển khai được Web API […]

  2. […] bài bài 68 và bài 69 và bài 70 các bạn đã hiểu được RESTful cũng như cách thức hoạt động của […]

  3. Thầy cho em hỏi là nếu mà dùng Web Service API RESTful Service làm các bài ở bài 43, 44, 45, 46 thì có bị ràng buộc dữ liệu không ạ! Em cảm ơn thầy!

  4. Thầy ơi e thắc mắc không biết tạo 1 project SQL server như server THANHTRAN của thầy như thế nào ạ?

    1. Em xem lại các bài tạo CSDL , hoặc search trên mạng

  5. thưa thầy, để upload 1 file lên server thì làm như thế nào ạ?

  6. Những phương thức để thêm/sửa có thể truyền tham số là 1 đối tượng (Food) thay vì một dãy những tham số dài (id, name, price, …) được không thầy?

    1. Hoàn toàn được. Các bài tiếp theo sẽ nói về cách này (Entity FrameWork)

  7. […] Bài 69: Xây dựng Web Service dùng API RESTful Service(phần 2) November 10, 2015 […]

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 )

Twitter picture

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

Facebook photo

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

Google+ photo

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

Connecting to %s