Bạn có thể trả lại HTML từ API JSON không?


25

Trong dự án hiện tại của tôi, tôi chịu trách nhiệm triển khai một dịch vụ liên quan đến việc tiêu thụ API RESTful mới được tạo, được ghi nhận là chỉ hỗ trợ JSON.

Máy khách luôn đưa ra các yêu cầu với tiêu đề chấp nhận là 'application / json' và loại nội dung của 'application / json'. Tuy nhiên, một số điểm cuối gửi phản hồi với loại nội dung HTML, thậm chí là phần thân HTML. Đối với tôi đây rõ ràng là cách tiếp cận sai và không bao giờ có thể được biện minh.

Trong suốt dự án, thực tế này đã được áp dụng trên hai nhà cung cấp khác nhau và hai dịch vụ khác nhau. Tôi thấy mình phải biện minh tại sao các dịch vụ cần phải thay đổi. Các nhà cung cấp tuyên bố rằng khách hàng nên đối phó với điều này và ngay cả thư viện lựa chọn REST của tôi đã bị nghi ngờ (RestPal) vì nó không đối phó với điều này theo mặc định 'ra khỏi hộp'.

Đây là một điểm chính của sự thất vọng. Tôi không thể tìm thấy nhiều tài liệu tham khảo để sao lưu lập luận của mình, tôi cho rằng điều này là do vấn đề này là quá rõ ràng.

Câu hỏi là tôi có thiếu thứ gì không? Tôi có phải là người phạm tội về điều này? Bạn có thể sử dụng API JSON không có loại ứng dụng / json nội dung trong kịch bản này không? Tài liệu tham khảo sẽ được đánh giá cao. Làm thế nào để bạn giải quyết tình huống này từ quan điểm thương mại?


1
Theo loại ngữ cảnh, bạn có nghĩa là tiêu đề HTTP loại nội dung?
Marjan Venema

Có, tôi đang đề cập đến tiêu đề loại nội dung HTTP. Đã chỉnh sửa.
phillip.darley

Chà, ít nhất họ không được gọi nó là "API JSON REST" khi đó là API REST của HTML.
Bergi

Câu trả lời:


28

Khi bạn đang gửi một accepttiêu đề yêu cầu một loại phương tiện cụ thể, máy chủ không nên gửi lại một cái gì đó khác và chắc chắn không phải với mã trạng thái 200 OK

Từ Restpotypes.org :

Nếu không có trường tiêu đề Chấp nhận, thì giả sử rằng máy khách chấp nhận tất cả các loại phương tiện. Nếu có trường tiêu đề Chấp nhận và nếu máy chủ không thể gửi phản hồi có thể chấp nhận theo giá trị trường Chấp nhận kết hợp, thì máy chủ NÊN gửi phản hồi 406 (không chấp nhận được).

(Nhấn mạnh của tôi)

Restpotypes.org lấy điều này từ tiêu chuẩn HTTP thực tế: Định nghĩa trường tiêu đề - Chấp nhận

Nói tóm lại: bạn không phải là người phạm tội. Các dịch vụ không tuân theo tiêu chuẩn HTTP nếu chúng trả về HTML khi tiêu đề chấp nhận đặc biệt yêu cầu chúng trả về application/jsonvà không có gì khác.


1
+1. Tôi đồng ý với câu trả lời này, nhưng thật đáng buồn là từ shouldnày được sử dụng nhiều lần trong thông số kỹ thuật HTTP. Chúng tôi phải bắt đầu một bản kiến ​​nghị trực tuyến để thay đổi những từ đó must.
Phản ứng

3
@MarjanVenema "nên" là chính xác vì trong phần 10 từ cùng một rfc có một lưu ý: "Máy chủ HTTP / 1.1 được phép trả về các phản hồi không được chấp nhận theo các tiêu đề chấp nhận được gửi trong yêu cầu. Trong một số trường hợp, điều này thậm chí có thể nên gửi phản hồi 406. "
imel96

1
Nếu một khách hàng yêu cầu một tài nguyên thực sự không có biểu diễn JSON, thì cho dù họ muốn JSON bao nhiêu, có lẽ tốt hơn hết là bạn nên nhận một thứ khác dứt khoát; bạn không được đảm bảo nhận được 406. Điều quan trọng là máy chủ phải mô tả loại nội dung của phản hồi thực sự là gì.
Donal Fellows

6
@DonalFellows: Không, họ sẽ tốt hơn nếu được thông báo về những gì thực sự là trường hợp. Máy chủ không nên gửi lại bất cứ thứ gì mà nó cho là phù hợp mà gửi phản hồi 406 Không chấp nhận được như đã nêu trong tiêu chuẩn. Hãy nhớ rằng khi khách hàng yêu cầu cụ thể một loại phương tiện và không chỉ định bất kỳ dự phòng nào, có lẽ không có cách nào xử lý bất kỳ loại phương tiện nào khác.
Marjan Venema

2
@ imel96: thực tế là internet chưa bao giờ nghiêm ngặt chính xác là điều đã dẫn đến sự khác biệt trong việc cố gắng hỗ trợ các trình duyệt khác nhau và các máy chủ hiện đang bị buộc phải tương thích ngược với html không hợp lệ vì đơn giản là có quá nhiều điều đó (và thật không may vẫn đang được tạo ra).
Marjan Venema

9

Ý bạn là gì khi nói về "API RESTful REST" - Tôi nghĩ vấn đề đầu tiên ở đây là bạn đang trộn lẫn các khái niệm (hoặc có thể là ai đó giữa bạn và các đối tác kỹ thuật của bạn tại "nhà cung cấp" của bạn).

API RESTful (cho dù bạn đang nói không thực sự nghỉ ngơi ở cấp 1 hoặc thứ gì đó ở cấp 3 trở lên cf http://martinfowler.com/articles/richardsonMaturityModel.html ) là về cách bạn tương tác với API không phải về định dạng của nội dung được gửi đến hoặc nhận từ. Nó thậm chí không phải về các giao thức hoặc cơ chế vận chuyển ...

Tương tự API JSON là một API hỗ trợ sử dụng JSON làm định dạng dữ liệu - nó có thể hoặc không thể nghỉ ngơi, nó có thể hoặc không được triển khai bằng HTTP và (và đây là điểm chính) nó có thể hoặc không hỗ trợ JSON duy nhất.

Một API tốt chạy trên HTTP (hợp lý khi cho rằng trong bối cảnh bạn đang nói về một api tiếp xúc với HTTP) sẽ cho phép bạn yêu cầu nội dung ở nhiều định dạng khác nhau và các định dạng đó có thể (và có thể nên) bao gồm HTML cũng như JSON và XML. Tại sao? Chà, nó sẽ làm cho việc học API dễ dàng hơn rất nhiều, về mặt khái niệm, nó cung cấp một UX dựa trên trình duyệt tức thì cho bất kỳ mục đích nào và v.v.

Câu hỏi thú vị sau đó trở thành nếu API của tôi, hỗ trợ nhiều định dạng nội dung, được gọi mà không được cho biết khách hàng mong đợi định dạng nào thì định dạng nào sẽ trả về ...? Điều này có xu hướng hướng tới một cuộc tranh luận tôn giáo - nhưng HTML cung cấp cho nhà cung cấp tùy chọn bao gồm thông tin hữu ích (như "nhớ đặt tiêu đề chấp nhận nội dung").

Để trả lời câu hỏi API, một API yên tĩnh và một hỗ trợ json hoàn toàn có thể trả về HTML nếu đó là nội dung được yêu cầu.


1
Tôi lấy cả hai điểm của bạn và đã chỉnh sửa câu hỏi của tôi cho phù hợp. Thực tế là dịch vụ RESTful không liên quan và tôi đã nêu chi tiết rằng khách hàng chấp nhận 'application / json' trong mỗi yêu cầu.
phillip.darley

Tôi muốn nói rằng "RESTful JSON API" có ý nghĩa rất rõ ràng.
gnasher729

1
Tôi muốn nói rằng các giáo viên của tôi đã nỗ lực rất nhiều để đảm bảo rằng chúng tôi hiểu tại sao "không bao giờ giả định" là một phần quan trọng của việc trở thành một lập trình viên giỏi
Murph

5

Máy khách luôn đưa ra các yêu cầu với tiêu đề chấp nhận là 'application / json' và loại nội dung của 'application / json'

Vâng, đây là điều chính xác để làm, nhưng không có nghĩa là nhà cung cấp quan tâm. Mặc dù tôi hoàn toàn hiểu sự thất vọng của bạn, bởi vì tôi cũng nghĩ rằng một dịch vụ JSON sẽ luôn cung cấp phản hồi JSON nhưng có nhiều ví dụ không phải là trường hợp đó.

Trong suốt dự án, thực tế này đã được áp dụng trên hai nhà cung cấp khác nhau và hai dịch vụ khác nhau. Tôi thấy mình phải biện minh tại sao các dịch vụ cần phải thay đổi. Các nhà cung cấp tuyên bố rằng khách hàng nên đối phó với điều này và ngay cả thư viện lựa chọn REST của tôi đã bị nghi ngờ (RestPal) vì nó không đối phó với điều này theo mặc định 'ra khỏi hộp'.

Vâng, tôi phải đồng ý với các nhà cung cấp. Đó là dịch vụ của họ và miễn là họ ghi lại rõ ràng các trường hợp đặc biệt để sử dụng nó, thì bạn không thể thực sự áp đặt rằng họ thay đổi nó. Đó là một bất lợi cho họ vì các nhà phát triển sẽ chậm chấp nhận API của họ và nếu họ lắng nghe những gì nhà phát triển cần thì họ sẽ thay đổi nó, nhưng thật đáng buồn là không có quy tắc nào họ phải tuân theo các tiêu chuẩn.

Câu hỏi là tôi có thiếu thứ gì không?

Tiêu đề yêu cầu không có nghĩa gì trừ khi chúng bị gián đoạn chính xác ở đầu bên kia. Tôi biết rằng nếu tôi phát triển API web bằng PHP, thì địa ngục với các tiêu đề yêu cầu. Tôi có thể trả lời với bất cứ điều gì tôi muốn. Trong khi đó, một dịch vụ được cấu hình trong IIS với C # cung cấp việc xử lý các tiêu đề yêu cầu, loại của chúng và xử lý loại phản hồi dễ dàng hơn nhiều. Nó có liên quan nhiều đến các công cụ mà nhà cung cấp sử dụng để xây dựng API.

Tôi đang bị phạm tội về điều này?

Có và không. Tôi có những người bạn phát triển, những người sẽ không thể vượt qua điều này. Họ sẽ trở nên quá cố định bởi vấn đề và không thể tiến hành các nhiệm vụ khác cho đến khi API hoạt động theo cách họ mong đợi nó hoạt động. Bây giờ đó là tầm cỡ.

Đó là một vấn đề bởi vì nhà cung cấp đã tạo ra "nhiều việc hơn" để hoàn thành nhiệm vụ của bạn. Bất cứ ai cũng sẽ thất vọng vì điều đó. Tôi biết tôi sẽ như thế.

Bạn có thể sử dụng API JSON không có loại ứng dụng / json nội dung trong kịch bản này không?

Tuyệt đối, nhưng nó không phải là một thực hành tốt.

Một khách hàng chỉ có thể cho máy chủ biết loại ngữ cảnh của a requestlà gì. Nó không có khả năng thực thi một kiểu nội dung cho response. Máy khách chỉ có thể thông báo cho máy chủ rằng nó sẽ accepttập hợp các loại nội dung có thể.

Định nghĩa trường tiêu đề

Trường chấp nhận tiêu đề yêu cầu có thể được sử dụng để chỉ định một số loại phương tiện được chấp nhận cho phản hồi. Các tiêu đề chấp nhận có thể được sử dụng để chỉ ra rằng yêu cầu được giới hạn cụ thể trong một nhóm nhỏ các loại mong muốn, như trong trường hợp yêu cầu cho một hình ảnh nội tuyến.

Khách hàng có thể yêu cầu một hình ảnh image/jpeg, nhưng máy chủ phản hồi text/htmlvà mã trạng thái 404nếu không tìm thấy hình ảnh. Máy chủ cũng có thể trả lời không chính xác. Có rất nhiều trang web Wordpress phản hồi text/htmlvà mã trạng thái 200cho các tệp không tìm thấy trang.

Bây giờ đó là tất cả thực hành BAD trên một phần của máy chủ. Điều tôi đang cố nói với bạn là điều đó hoàn toàn có thể, và xảy ra thường xuyên. Mọi người không biết những gì họ đang làm khi họ cấu hình những thứ này.

Tài liệu tham khảo sẽ được đánh giá cao. Làm thế nào để bạn giải quyết tình huống này từ quan điểm thương mại?

Tôi đã gặp vấn đề này trong một vài dự án. Bạn cung cấp postdữ liệu JSON cho máy chủ và nó trả về phản hồi JSON hoặc HTML.

Nó thực sự không phải là một vấn đề lớn để biết loại nào trong phản ứng. Nếu ký tự đầu tiên là {hoặc [bạn có thể giả sử JSON. Nếu đó là <bạn có thể giả sử HTML. Đó là cách tôi đã xử lý nó trong quá khứ. Đôi khi, lập trình viên đã viết API biết tất cả về các tiêu đề HTTP. Tất cả mọi thứ trở lại như text/htmlphản ứng. Nếu bạn may mắn, họ đã cấu hình Apache để mặc định text/plainđôi khi có thể giúp ích.

Những vấn đề này tồn tại và sẽ tiếp tục tồn tại trong tương lai. Giao tiếp từ máy chủ đến máy chủ là một hoạt động không được kiểm soát. Không có cơ quan quản lý nào sẽ đuổi một nhà cung cấp khỏi liên minh cho một máy chủ cung cấp phản hồi HTTP xấu.


Đây là nội tuyến với câu trả lời của @Marjan Venema nhưng một điểm quan trọng khác mà bạn nêu ra là tài liệu về hành vi này. Để thêm vào sự thất vọng của tôi, nhà cung cấp đã không ghi lại hành vi này. Kiểu nội dung khác nhau tùy thuộc vào trạng thái phiên, nhưng chỉ phản hồi JSON được ghi lại.
phillip.darley
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.