IT Staff

Blog về chuyên ngành IT

Web API

leave a comment »

Web API

ASP .NET Web API là thế hệ tiếp theo của WCF, cho phép chúng ta thiết kế một RESTful web service, tương thích với những flatforms và thiết bị có hỗ trợ giao thức HTTP, nghĩa là bạn nhập URL vào web browser và sẽ nhận được kết quả trả về từ web browser.
ASP .NET Web API có thể được hỗ trợ cài đặt sẵn cho Visual Studio 2010 hoặc Visual Studio 2012 RC. http://www.asp.net/web-api

Tạo một project mới: File > New > Project
Chọn Installed > Templates > Visual C# > Web > ASP.NET MVC 4 Web Application > đặt tên > OK.

Tiếp theo, trong dialog New ASP.NET MVC 4 Project, bạn chọn Web API và OK.

Add một class mới trong folder Model.

Đặt tên cho class này là User.cs và có nội dung như sau:
namespace HelloMarsWithWebAPI.Models
{
public class User
{
public int Id { get; set; }
public string Name { get; set; }
public string Favorites { get; set; }
public string Country { get; set; }
}
}

Thêm mới một controller tên là UsersController, và chọn template là Empty API Controller.

Nhập nội dụng như sau:

namespace HelloMarsWithWebAPI.Controllers
{
public class UsersController : ApiController
{
// Ta tạm thời khởi tạo danh sách user bằng tay
Users[] users = new Users[]
{
new User{Id=1, Name=”Dennis Ritchie”, Country=”America”, Favorites=”Programming”},
new User{Id=2, Name=”Yukihiro Matsumoto”, Country=”Japan”, Favorites=”Programming”},
new User{Id=3, Name=”Pinal Dave”, Country=”America”, Favorites=”Designed and implemented database architecture”}
};

/// <summary>
/// URI: /api/users
/// </summary>
/// <returns></returns>
public IEnumerable<User> GetAll()
{
return users;
}

/// <summary>
/// URI: /api/users/id
/// </summary>
/// <param name=”id”></param>
/// <returns></returns>
public User GetById(int id)
{
var user = users.FirstOrDefault(row => row.Id == id);
if (user == null)
{
var message = new HttpResponseMessage(HttpStatusCode.NotFound);
throw new HttpResponseException(message);
}

return user;
}

/// <summary>
/// URI: /api/users/?country=country
/// </summary>
/// <param name=”country”></param>
/// <returns></returns>
public IEnumerable<User> GetByCountry(string country)
{
return users.Where(row => string.Equals(row.Country, country, StringComparison.OrdinalIgnoreCase));
}

}
}

Nhấn F5 hoặc Ctrl + Shift + B để debug service.

Bạn truy xuất uri như sau:
http://localhost:51101/api/users
IE Browser sẽ trả về cho bạn file dữ liệu users.json như hình bên dưới.

Mở file users.json, bạn sẽ thấy file này chứa danh sách users:

Tiếp theo, mình truy xuất lấy user có id = 1 như sau:
http://localhost:51101/api/users/1
Và kết quả đúng như chúng ta mong đợi. IE browser trả về cho chúng ta 1 file có tên là 1.json, mở file này ta thấy toàn bộ thông tin của user có id = 1 và có dạng cấu trúc json.

Tiếp theo, ta lấy thông tin user theo phương thức GetByCountry như sau:
http://localhost:51101/api/users/?country=America
Nhìn vào kết quả trả về, ta thấy file có tên là users.json và nội dung chứa 2 users thuộc country là  America.

Chú ý:
– URI của model sẽ phụ thuộc vào tên controller, ví dụ với controller của User có tên là UserController thì URI cho model User sẽ bắt đầu là /user, hoặc với controller tên là UsersController thì URI bắt đầu sẽ là /users.
– Port 51101 được phát sinh tự động nên có thể của bạn sẽ khác khi khởi chạy service.
Tiếp theo, chúng ta sẽ bổ sung thêm các chức năng thêm, xóa, cập nhật thông tin cho user.

Tạo CRUD cho User

Đầu tiên, ta thêm một Repostitory cho User, gồm có interface và class implement cái interface này. Xem hình bên dưới:
Tạo một interface repository cho User có tên là IUserRepository:

Thêm đoạn code sau vào file IUserRepository.cs:
namespace HelloMarsWithWebAPI.Models
{
public interface IUserRepository
{
IEnumerable<User> GetAll();
User Get(int id);
User Add(User item);
void Remove(int id);
bool Update(User item);
}
}

Tạo một class có tên là UserRepository.cs để implement cái interface này, có nội dung như sau:

namespace HelloMarsWithWebAPI.Models
{
public class UserRepository : IUserRepository
{
private List<User> users = new List<User>();
private int _next_id = 1;

public UserRepository()
{
Add(new User { Id = 1, Name = “Dennis Ritchie”, Country = “America”, Favorites = “Programming” });
Add(new User { Id = 2, Name = “Yukihiro Matsumoto”, Country = “Japan”, Favorites = “Programming” });
Add(new User { Id = 3, Name = “Pinal Dave”, Country = “America”, Favorites = “Designed and implemented database architecture” });
}

#region * Implement the interface
public IEnumerable<User> GetAll()
{
return users;
}

public User Get(int id)
{
return users.Find(row => row.Id == id);
}

public User Add(User item)
{
item.Id = _next_id;
users.Add(item);

return item;
}

public void Remove(int id)
{
users.RemoveAll(row => row.Id == id);
}

public bool Update(User item)
{
int index = users.FindIndex(row => row.Id == item.Id);
if (index == -1)
return false;

users.RemoveAt(index);
users.Add(item);

return true;
}
#endregion
}
}

Quay lại class UsersController.cs, ta khai báo repository để quản lý thao tác CRUD.
Ta khai báo một repository như sau:
static readonly IUserRepository repository = new UserRepository();
* Get Resources
Ở trên, chúng ta đã thực thi 3 hàm để lấy dữ liệu về đó là: GetAll, GetById, và GetByCountry. Ta chỉnh sửa một số cho nội dung 3 hàm như sau:
public IEnumerable<User> GetAll()
{
return repository.GetAll();
}

public User GetById(int id)
{
User item = repository.Get(id);
if (item == null)
{
throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.NotFound));
}

return item;
}

public IEnumerable<User> GetByCountry(string country)
{
return repository.GetAll().Where(row => string.Equals(row.Country, country, StringComparison.OrdinalIgnoreCase));
}

* Create Resources
Để tạo user mới, client sẽ gửi một HTTP Request một message trong đó có body là nội dung chứa user mới này. Tên của request này có tên bắt đầu bằng “Post…” và một tham số truyền vào là user mới.
public HttpResponseMessage PostUser(User item)
{
item = repository.Add(item);
var response = Request.CreateResponse<User>(HttpStatusCode.Created, item);

string uri = Url.Link(“DefaultApi”, new { id = item.Id });
response.Headers.Location = new Uri(uri);

return response;
}
CreateResponse: serialize thông tin user mới tạo gửi vào body của response trả về.
Gắn uri của user mới tạo vào location trong phần header của response trả về.
Response code: status = 200 -> HttpStatusCode.OK, = 201 -> đã tạo thành công (HttpStatusCode.Created)

* Update Resources
Quy ước đặt tên hàm bắt đầu với “Put…”, Web API sẽ gửi yêu cầu cho PUT. Hàm này sẽ có hai tham số,  id và thông tin cập nhật user.
Id của user sẽ được lấy từ URI và user sẽ được deserialize từ request body. Thường thì id có type rất đơn giản và body có kiểu object.
public void PutUser(int id, User user)
{
user.Id = id;
if (!repository.Update(user))
{
throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.NotFound));
}
}

* Delete Resources
public HttpResponseMessage DeleteUser(int id)
{
repository.Remove(id);
return new HttpResponseMessage(HttpStatusCode.NoContent);
}
Response code: status = 200 -> HttpStatusCode.OK, = 202 -> đã tạo thành công (HttpStatusCode. Accepted), = 204 -> đã tạo thành công (HttpStatusCode. No Content)

Tài liệu tham khảo:
http://www.asp.net/web-api/overview/getting-started-with-aspnet-web-api/tutorial-your-first-web-api
http://www.asp.net/web-api/overview/creating-web-apis/creating-a-web-api-that-supports-crud-operations
http://www.asp.net/web-api/overview/extensibility/using-the-web-api-dependency-resolver
http://hintdesk.com/how-to-consume-asp-net-web-api-rc-with-restsharp/

Written by Xavier

Tháng Tám 3, 2013 lúc 9:43 sáng

Posted in Staff

Gửi phản hồi

Mời bạn điền thông tin vào ô dưới đây hoặc kích vào một biểu tượng để đăng nhập:

WordPress.com Logo

Bạn đang bình luận bằng tài khoản WordPress.com Log Out / Thay đổi )

Twitter picture

Bạn đang bình luận bằng tài khoản Twitter Log Out / Thay đổi )

Facebook photo

Bạn đang bình luận bằng tài khoản Facebook Log Out / Thay đổi )

Google+ photo

Bạn đang bình luận bằng tài khoản Google+ Log Out / Thay đổi )

Connecting to %s

%d bloggers like this: