Dịch vụ web RESTful  

Khi REST (là tên viết tắt của REpresentational State Transfer) đã được sử dụng phổ biến cho hầu hết các dịch vụ web và thiết bị di động, vì vậy việc hiểu rõ những kiến thức về tiêu chuẩn này là rất cần thiết...

Tổng quan

Khi REST (là tên viết tắt của REpresentational State Transfer) đã được sử dụng phổ biến cho hầu hết các dịch vụ web và thiết bị di động, vì vậy việc hiểu rõ những kiến thức về tiêu chuẩn này là rất cần thiết.

Sau hơn một thập kỷ, REST đã trở thành một trong những công nghệ quan trọng nhất cho các ứng dụng Web. Nó còn có khả năng phát triển nhanh chóng khi mà tất cả các công nghệ đều tiến tới định hướng API. Các ngôn ngữ phát triển chính hiện nay đều bao gồm một khung kiến trúc (framework) để có thể xây dựng các dịch vụ Web RESTful. Như vậy, điều quan trọng đối với các nhà phát triển và lập trình web là phải hiểu rõ về REST và các dịch vụ RESTful. Bài viết này giải đáp các thắc mắc về kiến ​​trúc REST, sau đó đi sâu vào việc sử dụng tiêu chuẩn này cho các tác vụ dựa trên API.

REST là một kiểu kiến ​​trúc cho các ứng dụng siêu phương tiện, nó chủ yếu được sử dụng để xây dựng các dịch vụ Web có trọng lượng nhẹ, ổn định và có thể khả năng mở rộng. Một dịch vụ dựa trên REST được gọi là một dịch vụ RESTful. REST không phụ thuộc vào bất kỳ giao thức nào, nhưng hầu như mọi ứng dụng RESTful đều sử dụng HTTP làm giao thức cơ sở. Bài viết này sẽ giải thích cơ chế tạo ra các dịch vụ RESTful với HTTP.

Tính năng của ứng dụng RESTful

Mỗi hệ thống đều sử dụng tài nguyên. Các tài nguyên này có thể là hình ảnh, tệp video, trang web, thông tin nghiệp vụ hoặc bất kỳ thứ gì có thể trình diễn trong hệ thống máy tính. Mục đích của một ứng dụng là cung cấp một cửa sổ (đầu vào) cho người sử dụng để họ có thể truy cập các tài nguyên này. Các nhà phát triển và nhà kiến trúc dịch vụ mong muốn ứng dụng này dễ triển khai, bảo trì, và có khả năng mở rộng dễ dàng. Một thiết kế dịch vụ RESTful có thể làm được nhiều hơn thế. Về cơ bản, các dịch vụ RESTful sẽ có các thuộc tính và tính năng sau:

• Hiển thị

• Thông báo

• Định dạng tài nguyên thống nhất (Uniform Resource Identifier (URI))

• Giao diện chuẩn hóa

• Phi trạng thái

• Liên kết giữa các tài nguyên

• Bộ nhớ sẵn

Hiển thị

Các dịch vụ RESTful tập trung vào xử lý các tài nguyên và cách cung cấp quyền truy cập vào các tài nguyên này. Một tài nguyên được coi là một đối tượng như trong lập trình hướng đối tượng (Object-oriented programming (OOP)). Một tài nguyên có thể bao gồm các tài nguyên nhỏ hơn. Khi thiết kế một hệ thống, điều đầu tiên cần làm là xác định các tài nguyên và  phương thức liên kết giữa các nguồn tài nguyên với nhau. Điều này tương tự như bước đầu tiên của việc thiết kế một cơ sở dữ liệu: Xác định các thực thể và các mối quan hệ.

Khi đã xác định được tài nguyên của mình, bước tiếp theo là tìm cách hiển thị các tài nguyên này trong hệ thống. Bất kì định dạng nào cũng có thể được sử dụng hiển thị các tài nguyên, vì REST không hạn chế định dạng hiển thị.

Ví dụ, tùy thuộc vào yêu cầu của người dùng, họ có thể quyết định sử dụng JSON (Ký hiệu đối tượng kịch bản JavaScript (JavaScript Object Notation)) hoặc XML. Nếu bạn đang xây dựng các trang Web sử dụng cho các cuộc gọi AJAX (JavaScript và XML không đồng bộ (Asynchronous JavaScript and XML)), thì JSON là một lựa chọn tốt. XML có thể được sử dụng để hiển thị cho các tài nguyên phức tạp hơn. Ví dụ, một tài nguyên được gọi là "Person" có thể được biểu diễn dưới dạng:

Hiển thị tài nguyên dưới định dạng JSON

?

1

2

3

4

5

6

{

"ID": "1",

"Name": "M Vaqqas",

"Email": "m.vaqqas@gmail.com",

"Country": "India"

}

 Hiển thị tài nguyên dưới định dạng XML

?

1

2

3

4

5

6

7

8

9

10

<Person>

 

<ID>1</ID>

 

<Name>M Vaqqas</Name>

 

<Email>m.vaqqas@gmail.com</Email>

 

<Country>India</Country>

</Person>

Trong thực tế, tùy thuộc vào loại máy khách hoặc yêu cầu của một số tham số, người sử dụng có thể sử dụng các định dạng khác nhau và quyết định cái nào để sử dụng cho một phản hồi. Cho dù sử dụng định dạng nào, một hiển thị tốt nên bao gồm một số đặc tính sau:

• Cả máy khách và máy chủ đều có thể hiểu được định dạng hiển thị này.

• Một hiển thị nên có khả năng hiển thị toàn bộ tài nguyên. Nếu có nhu cầu hiển thị một phần tài nguyên, thì phân tách tài nguyên này thành các tài nguyên con. Việc chia nhỏ tài nguyên lớn thành những tài nguyên nhỏ hơn cho phép bạn có thể hiển thị gọn hơn, nó cần ít thời gian hơn để tạo và chuyển, giúp các dịch vụ nhanh hơn.

• Hiển thị nên có khả năng liên kết tài nguyên với nhau. Điều này có thể được thực hiện bằng cách đặt URI hoặc ID duy nhất của tài nguyên có liên quan trong hiển thị (những phần dưới đây sẽ giải thích thêm về nội dung này).

Thông điệp

Người sử dụng và dịch vụ giao tiếp với nhau qua thông điệp. Người sử dụng gửi yêu cầu đến máy chủ và máy chủ sẽ phản hồi lại. Ngoài dữ liệu thực tế, các thông điệp này cũng chứa một số dữ liệu đặc tả về thông điệp. Điều quan trọng là nhà phát triển dịch vụ phải có  kiến thức và hiểu biết về định dạng của gói tin yêu cầu và phản hồi của giao thức HTTP 1.1 để thiết kế các dịch vụ Web RESTful.

Phản hồi giao thức HTTP

Hình dưới minh họa một định dạng của gói tin phản hồi HTTP

<HTTP Phiên bản>

<Mã phản hồi>

<Tiêu đề phản hồi>

<Nội dung chính phản hồi>

Hình  1 – Định dạng gói tin phản hồi HTTP

Máy chủ trả về <response code> (mã phản hồi), chứa trạng thái của yêu cầu. Mã phản hồi này thường là mã trạng thái HTTP 3 con số (the 3-digit HTTP status code).

<Response Header> (Tiêu đề phản hồi) chứa dữ liệu đặc tả và các cài đặt về thông báo phản hồi.

<Response Body> (Nội dung chính phản hồi) chứa nội dung cần hiển thị nếu yêu cầu thành công.

Ví dụ dưới đây minh họa cho Một phản hồi thực tế của một yêu cầu GET (yêu cầu hiển thị trong REST).

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

HTTP/1.1 200 OK

Date: Sat, 23 Aug 2014 18:31:04 GMT

Server: Apache/2

Last-Modified: Wed, 01 Sep 2004 13:24:52 GMT

Accept-Ranges: bytes

Content-Length: 32859

Cache-Control: max-age=21600, must-revalidate

Expires: Sun, 24 Aug 2014 00:31:04 GMT

Content-Type: text/html; charset=iso-8859-1

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns='http://www.w3.org/1999/xhtml'>

<head><title>Hypertext Transfer Protocol -- HTTP/1.1</title></head>

<body>

...

Mã phản hồi là 200 OK có nghĩa truy vấn thành công và thông điệp phản hồi chứa một hiển thị tài nguyên hợp lệ đã được yêu cầu. Trong trường hợp này, hiển thị là một tài liệu HTML được thông báo bởi tiêu đề Nội dung-Kiểu (Content-Type) trong tiêu đề phản hồi. Các thông điệp trong thư đều tự giải mã. Người thiết kế dịch vụ có thể nắm bắt và kiểm tra các yêu cầu và phản hồi HTTP bằng cách sử dụng một công cụ miễn phí có tên là Fiddler.

Gán địa chỉ cho tài nguyên

REST yêu cầu mỗi tài nguyên phải có ít nhất một URI. Dịch vụ RESTful sử dụng một hệ thống phân cấp thư mục như các URIs (có thể đọc được bởi con người) để gán địa chỉ cho các tài nguyên của nó. Công việc của URI là xác định một tài nguyên hoặc một tập hợp các tài nguyên. Một triển khai thực tế được xác định bởi một HTTP Verbs (các phương thức để thao tác trên tài nguyên bao gồm GET (Đọc), POST (Tạo ra), PUT (Cập nhật/Thay mới), PATCH (Cập nhật/Chỉnh sửa) và DELETE (Xóa). URI không được chứa bất kì thông điệp nào về một triển khai hoặc hành động. Điều này cho phép người thiết kế dịch vụ gọi cùng một URI với các triển khai HTTP khác nhau để thực hiện các hoạt động khác nhau. Giả sử có một cơ sở dữ liệu về con người và muốn giới thiệu nó với thế giới bên ngoài thông qua một dịch vụ. Một Person tài nguyên (Con người) có thể được giải quyết như thế này:

http://MyService/Persons/1

Địa chỉ URL theo định dạng:

Protocol://ServiceName/ResourceType/ResourceID

Dưới đây là một số đề xuất quan trọng để một URI có được cấu trúc tốt:

• Sử dụng danh từ số nhiều để đặt tên tài nguyên;

• Tránh sử dụng dấu cách để không tạo ra sự nhầm lẫn. Sử dụng dấu _ (dấu gạch dưới) hoặc - (dấu nối) thay thế;

• URI phân biệt chữ hoa chữ thường và có thể sử dụng tất cả các dạng URI chữ thường;

• Người thiết kế dịch vụ có các quy ước của riêng mình, nhưng phải nhất quán xuyên suốt dịch vụ. Đảm bảo ngưởi dùng biết về quy ước này. Người dùng xây dựng các URI trở nên dễ dàng hơn nếu họ biết về phân cấp tài nguyên và quy ước URI của người thiết kế dịch vụ đang triển khai;

• Một cool URI (URI lạnh) không bao giờ thay đổi; vì vậy hãy suy nghĩ trước khi quyết định về các cool URI cho dịch vụ.  Nếu người thiết kế cần thay đổi vị trí của tài nguyên, đừng loại bỏ URI cũ. Nếu có một yêu cầu cho URI cũ, người thiết kết dịch vụ sử dụng mã trạng thái 300 và chuyển hướng máy khách đến vị trí mới.

• Tránh động từ cho tên tài nguyên cho đến khi tài nguyên thực sự triển khai hoặc một quá trình. Động từ nên phù hợp hơn với tên của các triển khai. Ví dụ, dịch vụ RESTful không nên có tên URI như sau:

http://MyService/FetcthPerson/1 or http://MyService/DeletePerson?id=1.

Các Tham số truy vấn trong URI

URI trước được xây dựng với sự trợ giúp của tham số truy vấn:

http: // MyService / Persons? id = 1

Tuy nhiên, cách tiếp cận  sử dụng các tham số truy vấn này có một số nhược điểm như sau:

• Tăng độ phức tạp và giảm khả năng đọc, điều này sẽ tăng lên nếu dịch vụ có nhiều thông số hơn;

• Công cụ tìm kiếm, thu thập thông tin như Google từ chối địa chỉ URI với tham số truy vấn. Nếu đối với trường hợp đang phát triển Web, đây sẽ là một bất lợi lớn khi một phần dịch vụ Web sẽ bị ẩn khỏi các công cụ tìm kiếm.

Mục đích cơ bản của tham số truy vấn là cung cấp các tham số cho một triển khai cần các mục dữ liệu. Ví dụ: nếu muốn định dạng của một trình diễn được đưa ra bởi người sử dụng. Triển khai có thể sử dụng tham số như thế này:

http: // MyService / Persons / 1? format = xml & encoding = UTF8

hoặc là

http: // MyService / Persons / 1? format = json & encoding = UTF8

Cả các định dạng tham số và mã hóa trong URI chính phân cấp cha-con sẽ không chính xác về mặt logic vì chúng không có mối quan hệ như vậy:

http: // MyService / Persons / 1 / json / UTF8

Tham số truy vấn cũng cho phép tham số tùy chọn. Điều này không thể xảy ra trong một URI. Người phát triển chỉ nên sử dụng tham số truy vấn cho mục đích: cung cấp các giá trị tham số cho một quy trình.

Chuẩn hóa giao diện

Các hệ thống RESTful nên có một giao diện đồng bộ. Giao thức HTTP 1.1 cung cấp một tập hợp các phương thức để có thể phát triển một giao điện đồng bộ. Những phương thức này được quy định như bảng dưới đây:

Phương thức

Cách thực hoạt động trên máy chủ

Tính chất

GET

Truy cập tài nguyên (không thể chỉnh sửa)

Không làm thay đổi tài nguyên

PUT

Tạo một tài nguyên mới hoặc chỉnh sửa tài nguyên đã tồn tại

Trả về cùng một kết quả

POST

Tải lên một tài nguyên mới hoặc tài nguyên đã được chỉnh sửa

Không rõ

DELETE

Xóa tài nguyên.

Trả về cùng một kết quả

OPTIONS

Danh sách các hoạt động được chấp nhận trong tài nguyên.

Không làm thay đổi tài nguyên

HEAD

Phản hồi lại tiêu đê & không phản hồi lại nội dung thuộc tiêu đề.

Không làm thay đổi tài nguyên

Bảng 1 – Các phương thức hoạt động của HTTP 1.1

Một triển khai an toàn không làm ảnh hưởng đến giá trị ban đầu của tài nguyên. Ví dụ, phép toán "chia cho 1" là một phép toán an toàn bởi vì giá trị ban đầu sẽ không bao giờ thay đổi. Một triển khai không thay đổi giá trị (idempotent operation) là một hoạt động mang lại kết quả giống nhau cho dù thực hiện bao nhiêu lần. Ví dụ, phép toán "nhân với số không" thì kết quả luôn đưa về là số 0, kết quả luôn giống nhau. Tương tự, phương thức Safe HTTP không thực hiện bất kỳ thay đổi nào đối với tài nguyên trên máy chủ. Còn phương thức HTTP Idempotent cho ra cùng một kết quả bất kể nó được thực hiện bao nhiêu lần. Việc phân loại các phương thức như Safe (an toàn) hay Idempotent (không thay đổi kết quả) giúp dễ dàng dự đoán kết quả trong môi trường dễ thay đổi như môi trường Web nơi người dùng có thể định dạng lại yêu cầu đó.

GET có lẽ là giải pháp phổ biến nhất trên Web. Nó được sử dụng để thu thập tài nguyên.

HEAD chỉ trả về các tiêu đề phản hồi với một phần thân trống. Phương thức này có thể được sử dụng trong một kịch bản khi ngưởi sử dụng không cần toàn bộ biểu diễn của tài nguyên. Ví dụ, HEAD có thể được sử dụng để kiểm tra nhanh xem tài nguyên có tồn tại trên máy chủ hay không.

Phương thức OPTIONS được sử dụng để nhận danh sách các hoạt động cho phép trên tài nguyên. Ví dụ, xem xét yêu cầu sau đây:

?

1

2

OPTIONS http://MyService/Persons/1 HTTP/1.1

HOST: MyService

Dịch vụ sau khi phân quyền và xác thực, yêu cầu có thể trả về kết quả như sau:

?

1

2

200 OK

Allow: HEAD, GET, PUT

Dòng thứ hai chứa danh sách các triển khai dành cho máy khách.

Người thiết kế dịch vụ chỉ nên sử dụng các phương thức phù hợp với các mục đích và chức năng được thiết kế cho các phương thức này.

Ví dụ, không bao giờ sử dụng GET để tạo hoặc xóa một tài nguyên trên máy chủ. Nếu sử dụng như vậy, nó sẽ gây nhầm lẫn cho người sử dụng, dẫn tới các thao tác sai. Để minh họa, hãy xem xét yêu cầu này:

?

1

2

GET http://MyService/DeletePersons/1 HTTP/1.1

HOST: MyService

Theo đặc tả của giao thức HTTP 1.1, yêu cầu GET được cho là nạp tài nguyên từ máy chủ. Có thể dễ dàng xóa một tài nguyên như Person (Con người) trên máy chủ. Thay vì sử dụng phương thức GET, người thiết kế dịch vụ phải sử dụng phương thức DELETE (Xóa) để có thể xóa một nguồn tài nguyên theo thiết kế của RESTful như sau:

?

1

2

DELETE http://MyService/Persons/1 HTTP/1.1

HOST: MyService

REST đề xuất một giao diện thống nhất và HTTP cung cấp cho nhà phát triển giao diện thống nhất đó. Tuy nhiên, nó phục vụ nhà lập trình và các nhà phát triển để giữ cho nó thống nhất.

Sự khác biệt giữa PUT và POST

Hai phương thức này gây nhầm lẫn cho rất nhiều nhà phát triển. Sự khác biệt chính giữa PUT và POST là PUT là không thay đổi kết quả (idempotent) trong khi POST thì không. Bất kể ngưởi sử dụng gửi yêu cầu PUT bao nhiêu lần, kết quả sẽ giống nhau. POST không phải là một phương thức không thay đổi kết quả. Tạo POST nhiều lần có thể dẫn đến nhiều tài nguyên được tạo trên máy chủ.

Một khác biệt nữa là, đối với PUT, phương thức này phải luôn hoạt động cùng với URI. Điều này ngụ ý rằng máy khách sẽ có thể xây dựng URI mới cho một tài nguyên ngay cả khi nó chưa tồn tại trên máy chủ. Điều này là có thể khi người dùng chọn một tên hoặc ID duy nhất cho tài nguyên, giống như việc tạo một người dùng trên máy chủ yêu cầu người dùng chọn một ID duy nhất. Nếu người dùng không thể đoán được URI hoàn chỉnh của tài nguyên, thì không có giải pháp nào khác ngoài việc sử dụng POST.

Yêu cầu

Hoạt động

PUT http://MyService/Persons/

Không hoạt động. PUT yêu cầu một địa chỉ URI

PUT http://MyService/Persons/1

Tạo một tài khoản mới PersonID=1 nếu nó không tồn tại hoặc cập nhập lại cái cũ

   

POST http://MyService/Persons/

Tạo một tài khoản mới ngay khi được yêu cầu

POST http://MyService/Persons/1

Cập nhập lại tài khoản cũ tại PersonID=1

Bảng 2 –Phân biệt sự khác nhau giữa PUT và POST

Rõ ràng từ bảng hoạt động trên cho thấy một yêu cầu PUT sẽ không sửa đổi hoặc tạo nhiều hơn một tài nguyên bất kể nó được kích hoạt bao nhiêu lần (nếu URI giống nhau). Không có sự khác biệt giữa PUT và POST nếu tài nguyên đã tồn tại, cả hai cập nhật tài nguyên hiện có. Yêu cầu thứ ba (POST http: // MyService / Persons /) sẽ tạo một tài nguyên mỗi khi nó được kích hoạt. Rất nhiều nhà phát triển nghĩ rằng REST không cho phép POST được sử dụng cho hoạt động cập nhật; tuy nhiên, REST không áp dụng các hạn chế như vậy.

Ứng dụng

REST hay RESTful được sử dụng được rộng rãi thay cho dịch vụ web dựa trên SOAPWSDL. Việc các tập đoàn, công ty công nghệ như Yahoo, Google và Facebook hạn chế việc sử dụng các giao thức dựa trên nền tảng SOAP hay WSDL. Thay vào đó, họ hướng tới sử dụng các giao thức hướng tài nguyên, dễ khai thác và sử dụng như REST cho các dịch vụ của họ.

Trong Thông tư 39/2017/TT-BTTTT ngày 15/12/2017 của Bộ Thông tin và Truyền thông Ban hành Danh mục tiêu chuẩn kỹ thuật về ứng dụng công nghệ thông tin trong cơ quan nhà nước, Khuyến nghị áp dụng dịch vụ web RESTful và được xếp vào nhóm Tiêu chuẩn kết nối.

Đỗ Tiến Thành

Tài liệu tham khảo:

[1] http://www.drdobbs.com/web-development/restful-web-services-a-tutorial/240169069?pgno=2

[2] https://www.ibm.com/developerworks/webservices/library/ws-restful/

 

 

77 Go top

Ý kiến về Trang thông tin điện tử Cục Tin học hóa?



THÔNG KÊ TRUY CẬP
  • Người trực tuyến Người trực tuyến
    • Khách Khách 32
    • Thành viên Thành viên 0
    • Tổng Tổng 32
    • Tổng lượt truy cập: Tổng lượt truy cập: 10200580