openplanning

RESTful Web Service là gì?

  1. Web & Web Service
  2. RESTful Service là gì?
  3. Sử dụng các phương thức HTTP một cách rõ ràng
  4. Phi trạng thái (Stateless)
  5. Đưa ra cấu trúc thư mục giống các URI
  6. Truyền tải XML, JSON hoặc cả hai
  7. Java RESTful Service cho người mới bắt đầu

1. Web & Web Service

Trước khi trả lời câu hỏi về RESTful tôi muốn bạn phân biệt giữa web và web service.
Khi bạn gõ vào một URL vào trình duyệt và bạn nhận được một trang web. Đây là một nội dung mà thông thường bạn có thể đọc được, nó là nội dung dành cho người dùng ở đầu cuối.
Trong khi đó Web Service là một dịch vụ web, nó là một khái niệm rộng hơn so với khái niệm web thông thường, nó cung cấp các thông tin thô, và khó hiểu với đa số người dùng, chính vì vậy nó được sử dụng bởi các ứng dụng. Các ứng dụng này sẽ chế biến các dữ liệu thô trước khi trả về cho người dùng cuối cùng.
Ví dụ bạn vào một trang web ABC nào đó để xem thông tin về thời tiết và chứng khoán. Trang web đó sẽ hiển thị cho bạn các thông tin bạn muốn.

Để có được các dữ liệu về thời tiết ứng dụng ABC cần phải lấy thông tin từ một nguồn nào đó, nó có thể là một dịch vụ web chuyên cung cấp các số liệu thời tiết ứng với các vùng miền khác nhau.
Tương tự như vậy để có các số liệu về chứng khoán ứng dụng ABC cũng cần phải liên hệ với dịch vụ cung cấp các số liệu này. Các dữ liệu sẽ được chế biến trước khi trả về cho bạn là một trang web hoàn chỉnh.
Các Web Service thường cung cấp các dữ liệu thô mà nó khó hiểu đối với đa số người dùng thông thường, chúng thường được trả về dưới dạng XML hoặc JSON.

2. RESTful Service là gì?

RESTful Web Service là các Web Service được viết dựa trên kiến trúc REST. REST đã được sử dụng rộng rãi thay thế cho các Web Service dựa trên SOAP WSDL. RESTful Web Service nhẹ (lightweigh), dễ dàng mở rộng và bảo trì.
Những khái niệm đầu tiên về REST (REpresentational State Transfer) được đưa ra vào năm 2000 trong luận văn tiến sĩ của Roy Thomas Fielding (đồng sáng lập giao thức HTTP). Trong luận văn ông giới thiệu khá chi tiết về các ràng buộc, quy ước cũng như cách thức thực hiện với hệ thống để có được một hệ thống REST.
REST định nghĩa các quy tắc kiến trúc để bạn thiết kế Web services, chú trọng vào tài nguyên hệ thống, bao gồm các trạng thái tài nguyên được định dạng như thế nào và được truyền tải qua HTTP, và được viết bởi nhiều ngôn ngữ khác nhau. Nếu tính theo số dịch vụ mạng sử dụng, REST đã nổi lên trong vài năm qua như là một mô hình thiết kế dịch vụ chiếm ưu thế. Trong thực tế, REST đã có những ảnh hưởng lớn và gần như thay thế SOAPWSDL vì nó đơn giản và dễ sử dụng hơn rất nhiều.
REST là một bộ quy tắc để tạo ra một ứng dụng Web Service, mà nó tuân thủ 4 nguyên tắc thiết kế cơ bản sau:
  • Sử dụng các phương thức HTTP một cách rõ ràng
  • Phi trạng thái
  • Hiển thị cấu trúc thư mục như các URls
  • Truyền tải JavaScript Object Notation (JSON), XML hoặc cả hai.
Trong từ RESTful, thì từ ful chính là hậu tố (suffix) trong tiếng Anh, giống như từ help có nghĩa là giúp đỡ thì từ helpful là rất hữu ích.

3. Sử dụng các phương thức HTTP một cách rõ ràng

REST đặt ra một quy tắc đòi hỏi lập trình viên xác định rõ ý định của mình thông qua các phương thức của HTTP. Thông thường ý định đó bao gồm lấy dữ liệu, trèn dữ liệu, cập nhập dữ liệu hoặc xóa dữ liệu. Vậy khi bạn muốn thực hiện một trong các ý định trên hãy lưu ý các quy tắc sau:
  • Để tạo một tài nguyên trên máy chủ, bạn cần sử dụng phương thức POST.
  • Để truy xuất một tài nguyên, sử dụng GET.
  • Để thay đổi trạng thái một tài nguyên hoặc để cập nhật nó, sử dụng PUT.
  • Để huỷ bỏ hoặc xoá một tài nguyên, sử dụng DELETE.
Chú ý rằng các nguyên tắc ở trên là không bắt buộc, thực tế bạn có thể sử dụng phương thức GET để yêu cầu lấy dữ liệu, trèn, sửa hoặc xóa dữ liệu trên Server. Tuy nhiên REST đưa ra các nguyên tắc ở trên mục đích đưa mọi thứ trở lên rõ ràng và dễ hiểu.

Ví dụ dưới đây là cách bạn sử dụng GET để yêu cầu thêm dữ liệu trên server (Chú ý, đây là cách trái với nguyên tắc của REST).
Sử dụng GET để yêu cầu thêm một người dùng có tên Robert.
GET /adduser?name=Robert HTTP/1.1
Sử dụng GET để yêu cầu server đổi tên người dùng có tên Robert thành Smith.
GET /updateuser?name=Robert&newname=Smith HTTP/1.1
Và bây giờ theo các quy tắc của REST mọi thứ trở lên rõ ràng hơn.
Gửi lệnh HTTP POST để thêm dữ liệu:
POST /users/Robert HTTP/1.1
Host: myserver
Content-Type: application/xml
<?xml version="1.0"?>
<user>
<name>Robert</name>
</user>
Gửi một lệnh GET nếu bạn muốn lấy dữ liệu trên hệ thống.
GET /users/Robert HTTP/1.1
Host: myserver
Accept: application/xml
Gửi một lệnh PUT nếu bạn muốn cập nhập dữ liệu.
PUT /users/Robert HTTP/1.1
Host: myserver
Content-Type: application/xml
<?xml version="1.0"?>
<user>
 <name>Smith</name>
</user>
Gửi lệnh DELETE nếu bạn muốn xóa dữ liệu:
DELETE /users/Robert HTTP/1.1

4. Phi trạng thái (Stateless)

Một đặc điểm của REST là phi trạng thái (stateless), có nghĩa là nó không lưu giữ thông tin của client. Chẳng hạn bạn vừa gửi yêu cầu để xem trang thứ 2 của một tài liệu, và bây giờ bạn muốn xem trang tiếp theo (sẽ là trang 3). REST không lưu trữ lại thông tin rằng trước đó nó đã phục vụ bạn trang số 2. Điều đó có nghĩa là REST không quản lý phiên làm việc (Session).
Hình dưới đây minh họa một ứng dụng có lưu trữ trạng thái, nó biết người dùng đang xem trang số mấy. Và người dùng chỉ cần yêu cầu "Trang Tiếp theo" để nhận được trang mong muốn.
Với các thiết kế phi trạng thái, Client phải gửi yêu cầu rõ ràng, bao gồm số thự tự của trang cần xem.
Như vậy, các thành phần máy chủ phi trạng thái ít phức tạp hơn để thiết kế, viết và phân bổ thông qua máy chủ được cân bằng tải. Dịch vụ phi trạng thái không chỉ hoạt động tốt hơn, nó còn chuyển hầu hết vai trò duy trì trạng thái sang ứng dụng ở máy khách. Trong một dịch vụ mạng RESTful, máy chủ chịu trách nhiệm đưa ra các phản hồi và cung cấp một cách thức cho phép Client duy trì trạng thái ứng dụng của chính nó.

5. Đưa ra cấu trúc thư mục giống các URI

REST đưa ra một cấu trúc để người dùng có thể truy cập vào tài nguyên của nó thông qua các URL, tài nguyên ở đây là tất cả những cái mà bạn có thể gọi tên được (Video, ảnh, báo cáo thời tiết,..)
Bạn cần tạo ra các REST serivce để nó trả về cho người dùng các nguồn tài nguyên tương ứng.
Các địa chỉ REST service cần phải thật trực quan đến mức người dùng dễ đoán. Hãy nghĩ về một địa chỉ (URI) giống như một gợi ý rõ ràng, dễ đoán rằng nó đang trỏ tới cái gì và cung cấp tài nguyên gì. Tóm lại, cấu trúc của một URI nên được đơn giản, có thể dự đoán, và dễ hiểu.
Hãy xem một URL dưới đây, nó cung cấp thông tin thời tiết của một khu vực ứng với một ngày cụ thể, và nó dễ hiểu đối với người dùng.
http://myservice.com/weather/chicago/2016-09-27

http://myservice.com/weather/hanoi/2016-11-11
Một vài nguyên tắc bổ sung để lưu ý trong khi nói về cấu trúc địa chỉ của RESTful Web service là:
  • Giấu các đuôi tài liệu mở rộng của bản gốc trong máy chủ (.jsp, .php, .asp), nếu có, vì vậy bạn có thể giấu một số thứ mà không cần thay đổi địa chỉ Urls.
  • Để mọi thứ là chữ thường.
  • Thay thế các khoảng trống bằng gạch chân hoặc hoặc gạch nối (một trong hai loại).
  • Tránh các chuỗi yêu cầu càng nhiều càng tốt.
  • Thay vì sử dụng mã (404 Not Found) khi yêu cầu địa chỉ cho một phần đường dẫn, luôn luôn cung cấp một trang mặc định hoặc tài nguyên như một phản hồi.

6. Truyền tải XML, JSON hoặc cả hai

Khi Client gửi một yêu cầu tới web service nó thường được truyền tải dưới dạng XML hoặc JSON và thông thường nhận về với hình thức tương tự.
Đôi khi Client cũng có thể chỉ định kiểu dữ liệu nhận về mà nó mong muốn (JSON, hoặc XML,..), các chỉ định này được gọi là các kiểu MINE, nó được gửi kèm trên phần HEADER của request.

Dưới đây là các kiểu MINE phổ biến thường sử dụng với REST service.
JSON
application/json
XML
application/xml
XHTML
application/xhtml+xml
Ví dụ Client gửi một yêu cầu để lấy thông tin thời tiết, và yêu cầu dữ liệu trả về là định dạng XML.
GET /weather/chicago/2016-08-27 HTTP/1.1
Host: myservice.com
Accept: application/xml;q=0.5
Và dữ liệu nhận được:
<weather>
    <date>2016-08-27</date>
    <location>Chicago</location>
    <info>Hot</info>"//
</weather>
Trường hợp client yêu cầu dữ liệu trả về có định dạng JSON:
{
 "date": "2016-08-27",
 "location": "Chicago",
 "info": "Hot"
}