REST - Trao đổi giữa đàm phán nội dung thông qua tiêu đề Chấp nhận so với tiện ích mở rộng


40

Tôi đang làm việc thông qua việc thiết kế API RESTful. Chúng tôi biết rằng chúng tôi muốn trả về JSON và XML cho bất kỳ tài nguyên nào. Tôi đã nghĩ rằng chúng tôi sẽ làm một cái gì đó như thế này:

GET /api/something?param1=value1
Accept:  application/xml (or application/json)

Tuy nhiên, ai đó đã sử dụng tiện ích mở rộng cho việc này, như vậy:

GET /api/something.xml?parm1=value1 (or /api/something.json?param1=value1)

Sự đánh đổi với những cách tiếp cận này là gì? Có phải tốt nhất là dựa vào tiêu đề chấp nhận khi tiện ích mở rộng không được chỉ định, nhưng tôn trọng tiện ích mở rộng khi được chỉ định? Có một nhược điểm cho cách tiếp cận đó?


Bạn đang sử dụng máy chủ web nào? và làm thế nào để phân tích URL?
Dipan Mehta

1
Tôi không có ý tưởng về mặt kỹ thuật (máy chủ) của mọi thứ. Điều đó đang được nói, tôi thích cách tiếp cận của bạn, bởi vì nó sử dụng tiêu chuẩn http, giúp dễ hiểu hơn (ví dụ khi một người khác có nghĩa vụ thực hiện một số bảo trì trên đó vài năm). Bạn có thể dựa vào tiện ích mở rộng khi chấp nhận không được chỉ định hoặc có giá trị không mong muốn, nhưng tôi sẽ luôn đi theo cách tiêu chuẩn trước.
Treb

@Dipan Tôi đang hack điều này với API Web MVC4 (vẫn đang trong giai đoạn thử nghiệm). Nó sử dụng trừu tượng định tuyến của ASP.NET, khá đẹp.
Brandon Linton

1
@Treb Yeah Tôi rất hâm mộ việc sử dụng giá trị tiêu đề chấp nhận. Tôi tự hỏi nếu có bất kỳ nhược điểm để hỗ trợ cả hai.
Brandon Linton

Câu trả lời:


38

Điều này, "Tuy nhiên, về mặt triết học - cách tiếp cận đầu tiên là cách tiếp cận duy nhất." Và đây là "Cách tiếp cận RESTful chính thức phù hợp là sử dụng tiêu đề Accept:". được nhận thức rộng rãi là trường hợp, nhưng cũng hoàn toàn không chính xác .

Đây là một đoạn ngắn từ Roy Fielding (người định nghĩa REST) ​​...

"phần 6.2.1 không nói rằng nên sử dụng đàm phán nội dung mọi lúc." trích dẫn

Cuộc hội thoại cụ thể đó nằm trong ngữ cảnh của tiêu đề 'Ngôn ngữ chấp nhận:', nhưng cũng áp dụng tương tự cho tiêu đề 'Chấp nhận:', như được làm rõ sau này trong phản hồi của anh ấy ...

"Tôi không biết tại sao mọi người không thể thấy liên kết thứ hai và thứ ba trên trang đầu

http://www.ics.uci.edu/~fielding/pub/dissertation/top.htm

chỉ ra hai phiên bản PDF. "

Điều ông muốn nói là không có vấn đề gì trong việc sử dụng các điểm cuối khác nhau cho các biểu diễn khác nhau của cùng một dữ liệu nguồn. (Trong trường hợp này, một điểm cuối .html và hai điểm cuối .pdf khác nhau.)

Cũng trong một cuộc thảo luận tương tự, lần này liên quan đến ưu điểm của việc sử dụng tham số truy vấn so với sử dụng tiện ích mở rộng tệp cho các loại phương tiện khác nhau ...

"Đó là lý do tại sao tôi luôn thích các tiện ích mở rộng. Cả hai lựa chọn đều không liên quan gì đến REST." trích dẫn

Một lần nữa, điều đó hơi khác so với Chấp nhận so với các phần mở rộng tên tệp, nhưng lập trường của Fielding vẫn rõ ràng.

Trả lời - nó thực sự không quan trọng lắm. Sự đánh đổi giữa hai người không quá quan trọng và cả hai đều là phong cách chấp nhận được.


3
Câu trả lời cân bằng tuyệt vời. Tôi nghĩ rằng đôi khi tôi sẽ thêm 'rõ ràng' từ URI rằng một nội dung nhất định được dự định. ví dụ: phần mở rộng .html hoặc phần mở rộng .pdf trong URI. Và trong trường hợp này, thực sự không cần hỗ trợ đàm phán nội dung và việc có nội dung ẩn trong URI giúp con người chia sẻ URI dễ dàng hơn và sử dụng nó để liên kết với mọi thứ theo cách họ có thể tiêu thụ ngay lập tức. Trong các trường hợp khác như bạn muốn tránh các tiện ích mở rộng trong URI của mình và / hoặc bạn muốn hiển thị API web hỗ trợ nhiều loại nội dung json / XML như nhau, tiêu đề chấp nhận có thể phù hợp hơn.
Tim Lovell-Smith

Cập nhật câu trả lời để chứa các liên kết mới. Tôi nghĩ rằng các nhóm yahoo đã thay đổi cấu trúc của họ xung quanh.
Phil Sturgeon

Tôi không đồng ý. Ngôn ngữ mô tả tài nguyên được máy chủ trả về phải không liên quan đến logic nghiệp vụ được thực hiện bởi điểm cuối dịch vụ. Có nhiều URI cho cùng một điểm cuối dịch vụ, chỉ để chứa các ngôn ngữ mô tả tài nguyên khác nhau, có vẻ như là một sự hiểu lầm về cách xây dựng URI REST.
Dejay Clayton

10

Cách tiếp cận RESTful chính thức thích hợp là sử dụng Accept:tiêu đề.

Tuy nhiên, bạn phải cẩn thận để không phá vỡ tính lưu trữ, đây là một trong những yêu cầu của REST. Bạn cần phải có Vary: Accepttiêu đề và bộ nhớ cache để hiểu nó. Trong thế giới lý tưởng bạn sẽ có nó, nhưng trong cuộc sống thực, phần kê của bạn có thể thay đổi. Vì vậy, giải pháp thứ hai không sạch sẽ, nhưng nó có thể thực tế hơn.

Ngoài ra, lưu ý rằng một số trình duyệt rất cũ được sử dụng để bỏ qua các tiêu đề, thay vào đó dựa vào tiện ích mở rộng.


1
Thực tế không chính xác. Xem câu trả lời được chấp nhận.
Phil Sturgeon

9

Về mặt kỹ thuật, điều đó không thực sự quan trọng - máy chủ web của bạn sẽ có thể vượt qua quá trình một cách thích hợp như mong muốn. (Tôi đang giả sử điều này nhưng không giống như một showstopper).

Tuy nhiên, về mặt triết học - cách tiếp cận đầu tiên là cách tiếp cận duy nhất. Trong REST, URL thực sự chỉ trỏ đến một URI - vốn chỉ là một tài nguyên. Hãy suy nghĩ một lúc tài nguyên này giống như đối tượng trong lập trình hướng đối tượng. Bạn nói chuyện với tài nguyên này chỉ thông qua 4 phương thức (còn gọi là GET / POST / PUT / DELETE -hoặc nếu bất cứ điều gì vận chuyển cho phép) nhưng phương thức đó không trở thành mô tả về đối tượng. Tương tự, các khía cạnh của giá trị trả về không phải là URI. Đối tượng vẫn là một cái gì đó và không phải là một cái gì đó hoặc một cái gì đó

Giả sử nếu bạn không muốn sử dụng tiêu đề Chấp nhận, nhưng nếu bạn vẫn muốn thực sự là REST về mặt triết học, tôi sẽ không bận tâm điều gì đó như:

GET /api/something?parm1=value1&return_type=xml

như trái ngược với

GET /api/something.xml?parm1=value1 (or /api/something.json?param1=value1)

Nhưng như tôi đã nói, sự khác biệt này chỉ là triết học.


+1 Dipan, bạn đúng ngoại trừ một điều: / api / cái gì đó? Return_type = xml vẫn không yên . Lý do nó không RESTful là các URL mờ. IOW, từ quan điểm giao thức, không có sự khác biệt giữa / api / Something / xml và / api / Something? Xml. Xem w3.org/DesignIssues/Axioms.html .
Đánh dấu E. Haase

0

@vartec: Tôi nghĩ bạn sai

Nguyên tắc RESTful chính thức phù hợp nói rằng không có gì phải được ẩn trong các tiêu đề HTTP vì đó là URI được hiển thị hoặc được tham chiếu, mọi chi tiết về yêu cầu / phản hồi phải được cung cấp như một phần của URI

Do đó, tôi thực sự khuyên bạn nên tránh sử dụng tiêu đề để biết chi tiết về yêu cầu và phản hồi và bám sát

 GET /api/something.xml?parm1=value1 (or /api/something.json?param1=value1)

Tôi không thể tìm thấy các tài liệu tham khảo một cách nhanh chóng, nhưng tôi sẽ đăng lại cùng với họ (thực ra bạn có thể tham khảo cuốn sách xuất bản O'reilly "Dịch vụ web RESTful" ( http://shop.oreilly.com/product/9780596529260.do ) xác nhận tương tự


17
-1 Hoàn toàn sai. Đối với một điều, URL được gửi trong các tiêu đề HTTP. Hơn nữa, mỗi URL riêng biệt phải đại diện cho một tài nguyên riêng biệt. Các mã hóa XML và JSON của cùng một nội dung rõ ràng không phải là 2 tài nguyên khác nhau; chúng là 2 đại diện khác nhau của cùng một tài nguyên.
Đánh dấu E. Haase

Tiêu đề HTTP là nơi hợp pháp và được đề xuất để lưu trữ "siêu dữ liệu nhắn tin", chẳng hạn như: thông tin bảo mật, số nhận dạng tương quan, ID phiên, bối cảnh giao dịch, định dạng dữ liệu. Loại thông tin này không nên làm lộn xộn URL hoặc tải trọng tin nhắn của bạn.
Paulo Merson
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.