Hậu quả của việc không thực hiện API REST theo cách thức đúng đắn?


8

Tôi sẽ hỏi câu hỏi này theo cách này - những lo ngại về công nghệ phần mềm khi không triển khai API REST của tôi theo cách "đúng" là gì?

Bạn có ý nghĩa gì về cách "đúng"? Chà, cho phép tôi giải thích nhận thức của mình về cách đúng đắn, sau đó tôi sẽ cho bạn biết tôi đang làm như thế nào (cũng vậy, giả sử tôi đang nói về API JSON REST).

Đúng cách

  1. Không quốc tịch. Đây là phần tôi nhận được. Khách hàng duy trì trạng thái luôn luôn 100% thời gian mãi mãi. Đó không phải là công việc của máy chủ, đó là của khách hàng.

  2. Các hành động và phản ứng dự kiến ​​cho mỗi động từ:

    • NHẬN - Nhận toàn bộ tài nguyên được chỉ định toàn bộ, chỉ bị giới hạn bởi ủy quyền trong yêu cầu hoặc tham số truy vấn. Điều này đảm bảo không sửa đổi bất kỳ tài nguyên nào trong quy trình.
    • POST - Đưa ra toàn bộ mô tả tài nguyên (như đối tượng JSON), tạo tài nguyên, sau đó trả về tài nguyên đó, với bất kỳ thuộc tính phía máy chủ nào cũng được tạo, chẳng hạn như ngày hoặc ID.
    • XÓA - Xóa một tài nguyên đã chỉ định, chỉ cung cấp một số loại 200 OK làm phản hồi
    • PUT - Đưa ra toàn bộ khai báo đối tượng làm đầu vào, cập nhật tài nguyên tại một vị trí cụ thể, cập nhật tất cả các trường của tài nguyên cho từng trường được đưa ra trong đầu vào. Để rõ ràng, điều này hy vọng toàn bộ đối tượng sẽ được thông qua dưới dạng đầu vào. Toàn bộ tài nguyên cập nhật được trả về, với tất cả các trường (theo ủy quyền hoặc bất kỳ cờ đầu vào nào khác).
    • VĂN BẢN - Chỉ đưa ra các trường mong muốn được sửa đổi cho tài nguyên, chỉ cập nhật các trường trong tài nguyên đã chỉ định được cung cấp làm đầu vào. (Đây là nơi tôi không rõ ràng): Toàn bộ tài nguyên được trả lại? (Hay đó chỉ là các lĩnh vực được cập nhật? Dunno. Đừng quan tâm.)
  3. Đường dẫn tài nguyên. Với mối quan hệ của các tài nguyên với nhau, một đường dẫn tài nguyên có thể trông giống như một trong:
    • / Parentresource /: id
    • / Parentresource /: id / childresource
    • / Parentresource /: id / childresource /: childId
    • / Parentresource /: id / childresource /: childId / subresource /: subresourceId (Trong ví dụ này, nguồn con thuộc về nguồn con, thuộc về tài nguyên gốc).

Cách tôi muốn làm

Trên đây là sự hiểu biết của tôi về cách API REST hoạt động. Bây giờ hãy để tôi liệt kê một số biến thể của tôi ở trên:

  1. PUT / PATCH - Điểm vượt qua trong toàn bộ tài nguyên để sửa đổi là gì? Tôi chỉ sử dụng PUT để sửa đổi tài nguyên và tôi chỉ chuyển vào các trường tôi muốn được cập nhật. Do đó, tôi không có nhu cầu sử dụng VÒI
  2. Đường dẫn tài nguyên - Tôi sử dụng GUID trong ứng dụng của mình. Kết quả là, chúng sẽ là duy nhất trên toàn cầu. Tại sao tôi cần đường dẫn tài nguyên đầy đủ, bao gồm cả tài nguyên gốc, nếu tôi chỉ có thể tham chiếu duy nhất một nguồn cung cấp phụ? Giống như:
     
    / subresource /: subresourceId
     
    Nếu tôi được làm điều đó một cách "đúng", cố gắng để tham khảo các subresource sẽ đòi hỏi một đường dẫn đầy đủ như:
     
    / parentresource /: id / childresource /: childId / subresource /: subresourceId
     
    là tất cả những gì cần thiết ? Bởi vì bây giờ tôi phải xử lý lỗi bổ sung nếu đường dẫn của tôi chứa một: subresourceId không thực sự thuộc sở hữu của một: childId và ditto cho một: childId không thuộc sở hữu của cha mẹ: id. Phía máy chủ của tôi đang chăm sóc ủy quyền tài nguyên. Tôi không thể chỉ tham khảo tài nguyên, chứ không phải là đường dẫn đầy đủ?

  3. Các phản ứng trở lại. Ví dụ, giả sử cấu trúc dữ liệu của tôi là một cây phân cấp, không có giới hạn thực tế về độ sâu của cây. Tài nguyên nằm ở các cấp độ khác nhau trên cây, theo kiểu phân cấp.

    • NHẬN là rõ ràng. Nếu tôi nhận được toàn bộ cây này, tôi mong đợi toàn bộ cây là một phản hồi, với các tài nguyên được chứa trong các tài nguyên.
    • Nếu tôi POST để tạo tài nguyên mới, PUT để cập nhật hoặc XÓA để xóa, tôi muốn xem deltas trong cây, thay vì chỉ nhìn thấy tài nguyên mà tôi đã tạo / cập nhật / xóa. Tôi không muốn phải gọi lại GET của cây mẹ sau mỗi lần POST, PUT hoặc DELETE, đặc biệt là nếu có ít thay đổi đối với cây và tôi chỉ muốn nhìn thấy vùng đồng bằng.

Hy vọng câu hỏi của tôi là rõ ràng.

Nếu bạn đã thấy một triển khai REST như tôi đã mô tả, bạn sẽ trố mắt và nói với tôi về những lo ngại về kỹ thuật phần mềm của bạn chứ? Nếu vậy, họ sẽ là gì?


4
Thật kỳ lạ, không có mối quan tâm nào của bạn liên quan đến các ràng buộc về kiến ​​trúc của REST. Các câu hỏi của bạn bị ràng buộc chặt chẽ với ngữ nghĩa WEB và HTTP. Có vẻ như bạn không thoải mái với những điều cuối cùng này, điều gì khiến tôi suy nghĩ, Tại sao phải tạo giao diện web? Mặt khác, không có thứ gọi là "đúng cách" hay "sai cách". Chỉ cần thực hiện mà bộ tốt nhất nhu cầu của bạn. Những gì bạn gọi là "đúng" chỉ là "thân thiện với web" và "thân thiện với nhà phát triển". Càng "thân thiện với web" thì càng có nhiều lợi thế từ kiến ​​trúc WWW. Đó sẽ là điểm của việc làm "mọi thứ" trên web.
Laiv

Nguy cơ đi chệch khỏi REST là ai đó mong đợi giao diện RESTful sẽ bị nhầm lẫn bởi hành vi của ứng dụng web của bạn. Tuy nhiên, những gì bạn đề xuất thậm chí dường như không đi chệch hướng nhiều đến mức gây ra sự nhầm lẫn hoàn toàn, vì vậy tôi sẽ lập luận rằng những gì bạn đề xuất là hoàn toàn tốt. Chỉ cần thêm tài liệu!
Neil

@Laiv, bạn đặt ra một câu hỏi hay - tại sao lại tạo giao diện web? Bởi vì tôi không quen thuộc với bất kỳ kiến ​​trúc nào khác hỗ trợ khung kết xuất phía máy khách như React hoặc Vue, hơn là có một giao diện web gửi dữ liệu mà tôi cần. Để rõ ràng, tôi không muốn kết xuất phía máy chủ, vì lý do linh hoạt và hiệu suất. Tôi cũng biết rằng GraphQL là một lựa chọn, nhưng tôi cực kỳ lạ lẫm với nó.
Michael Plautz

GraphQL không phải là một kiểu kiến ​​trúc chỉ là một ngôn ngữ truy vấn nữa với rất nhiều mã nồi hơi dưới mui xe. bạn có thể tận dụng WWW mà không cần đi REST. Vẫn có WebSockets hoặc ProtocolBuffers. nếu ứng dụng của bạn không hoàn toàn là chuyển giao biểu tượng, thì REST không phục vụ bạn.
Laiv

Câu trả lời:


3

Câu trả lời cơ bản chung ở đây là ý tưởng của bạn có thể hoạt động ở cấp độ kỹ thuật, nhưng điều đó không có nghĩa là chúng tuân thủ các quy ước được tiêu chuẩn hóa của REST.


  1. PUT / PATCH - Điểm vượt qua trong toàn bộ tài nguyên để sửa đổi là gì? Tôi chỉ sử dụng PUT để sửa đổi tài nguyên và tôi chỉ chuyển vào các trường tôi muốn được cập nhật. Do đó, tôi không có nhu cầu sử dụng VÒI

Ý tưởng của bạn hoạt động ở cấp độ kỹ thuật, nhưng đơn giản đó không phải là cách REST được mô tả. Hãy nhớ rằng bất kỳ cuộc thảo luận nào về mã làm việc (nghĩa là không có lỗi biên dịch hoặc thời gian chạy) luôn luôn là vấn đề quy ước , không nhất thiết phải có ưu thế kỹ thuật rõ ràng.


  1. Đường dẫn tài nguyên - Tôi sử dụng GUID trong ứng dụng của mình. Kết quả là, chúng sẽ là duy nhất trên toàn cầu. Tại sao tôi cần đường dẫn tài nguyên đầy đủ, bao gồm cả tài nguyên gốc, nếu tôi chỉ có thể tham chiếu duy nhất một nguồn cung cấp phụ?

Có nhiều sắc thái đối với cách chúng ta định nghĩa các thực thể "con / cha mẹ". Thông thường nhất, nó đề cập đến mối quan hệ một-nhiều (cha mẹ với con cái).

Tuy nhiên, tôi nghi ngờ rằng đối với REST, một phần của điều khiến trẻ trở thành một đứa trẻ là có một kỳ vọng là chỉ có thể truy cập chúng thông qua cha mẹ, rằng chúng không mang theo định danh duy nhất trên toàn cầu (và được biết đến bên ngoài).
Tôi nghi ngờ điều này tuân theo cùng một triết lý (nhưng không nhất thiết phải có cùng lý do) như của các tập hợp (và nguồn gốc của chúng) trong Phát triển theo hướng tên miền .

Tập hợp DDD là một cụm các đối tượng miền có thể được coi là một đơn vị. Một tập hợp sẽ có một trong các đối tượng thành phần của nó là gốc tổng hợp. Bất kỳ tài liệu tham khảo từ bên ngoài tổng hợp chỉ nên đi đến gốc tổng hợp .

Trong trường hợp của bạn, những gì bạn gọi là các hàm "cha" là gốc tổng hợp. Điểm liên lạc duy nhất (nếu bạn muốn) cho người gọi bên ngoài.

Bạn có thể muốn kết luận rằng con bạn thực sự là một tập hợp khác nhau. Đó có thể là trường hợp, nhưng tôi muốn đưa ra một cảnh báo với quyết định đó. Bạn không nên căn cứ kiến ​​trúc của mình vào loại cụ thể của một lĩnh vực. Bạn không có cách nào để biết liệu bạn sẽ luôn tiếp tục sử dụng ID duy nhất trên toàn cầu cho tất cả các thực thể của bạn. Nếu điều đó thay đổi, vì bất kỳ lý do gì, bạn sẽ thỏa hiệp khả năng tồn tại của kiến ​​trúc REST; vì bạn có thể rơi vào tình huống mà đứa trẻ không còn nhận dạng duy nhất và do đó cần phải được tham chiếu thông qua cha mẹ của nó.


  1. Nếu tôi POST để tạo tài nguyên mới, PUT để cập nhật hoặc XÓA để xóa, tôi muốn xem deltas trong cây, thay vì chỉ nhìn thấy tài nguyên mà tôi đã tạo / cập nhật / xóa.

Bạn đang vi phạm trật tự hoạt động của thiết kế. API REST được dành riêng cho mục đích bất khả tri của người tiêu dùng. API không nên được xây dựng theo thông số kỹ thuật của một trong những người tiêu dùng của nó.

Khi bạn nói "Tôi muốn nhìn thấy vùng đồng bằng trên cây", điều bạn thực sự nói là "ứng dụng tiêu thụ chỉ có nhu cầu nhìn thấy vùng đồng bằng trên cây". Nhưng điều đó không quan trọng với api REST. Nó chỉ cung cấp một cách tiếp cận tiêu chuẩn hóa.

Đó là bản chất của các phương pháp tiêu chuẩn hóa thường thiếu các công cụ tùy biến cao , và thay vào đó ưu tiên các công cụ được sử dụng phổ biến nhất .


Bạn có thể đi chệch khỏi con đường? Vâng, nó sẽ làm việc trên một mức độ kỹ thuật. Nhưng nó sẽ không còn là REST thuần túy nữa. Đây là một cái gì đó rất bối cảnh và bạn cần phải cân nhắc các tùy chọn.

  • Nếu bạn đang tạo một API dự kiến ​​sẽ phục vụ nhiều người tiêu dùng khác nhau, thì tôi khuyên bạn nên gắn bó với REST một cách tốt nhất có thể.
  • Nếu bạn đang xây dựng một API sẽ chỉ có một người tiêu dùng cũng do bạn phát triển; sau đó không có nhu cầu thực sự để gắn bó với REST thuần túy.
  • Đi lạc từ đường dẫn có nghĩa là bạn sẽ phải ghi lại cách bạn đi lạc để các nhà phát triển khác vẫn có thể hiểu ý nghĩa của nó. Nếu bạn gắn bó với REST thuần túy, bạn không phải viết tài liệu và các nhà phát triển khác không phải mất thời gian và công sức để tìm ra cách tiếp cận tùy chỉnh của bạn.

9

các mối quan tâm về công nghệ phần mềm khi không triển khai API REST của tôi theo cách "đúng" là gì?

Theo tôi, yếu tố cơ bản là khả năng ủy thác công việc cho các thành phần chung chỉ biết các tiêu chuẩn chứ không phải trường hợp kinh doanh cụ thể của bạn.

Nếu bạn đang tuân thủ giao diện thống nhất, thì các bên khác sẽ dễ dàng hơn trong việc xây dựng các thành phần tích hợp độc đáo với bạn.

Đây là văn bản Fielding năm 2008

REST dành cho các ứng dụng dựa trên mạng tồn tại lâu dài trải rộng trên nhiều tổ chức.

Một trong những cách chúng tôi quản lý "sống lâu" là bằng cách có một tiêu chuẩn rõ ràng mô tả ngữ nghĩa của các thông điệp chúng tôi đang truyền. Nếu mọi người đồng ý PUTnghĩa là gì , thì người tiêu dùng và nhà sản xuất của những yêu cầu đó có thể được phát triển độc lập và các thành phần trung gian giữa hai người có thể thực hiện các hành động hợp lý mà không cần biết chi tiết về thông điệp trong ngữ cảnh cụ thể của bạn.

PUT / PATCH - Điểm vượt qua trong toàn bộ tài nguyên để sửa đổi là gì? Tôi chỉ sử dụng PUT để sửa đổi tài nguyên và tôi chỉ chuyển vào các trường tôi muốn được cập nhật. Do đó, tôi không có nhu cầu sử dụng VÒI

Điểm quan trọng trong việc sử dụng PUTlà gì?

PURPLE /014d8c83-604d-4cf0-a6ba-e1f7ef8c4898 HTTP/1.1
...

Đó là một dòng yêu cầu hoàn toàn hợp lệ cho một thông điệp HTTP và sự thay đổi về ngữ nghĩa sẽ không gây nhầm lẫn cho bất kỳ ai.

Tương đương

POST /014d8c83-604d-4cf0-a6ba-e1f7ef8c4898 HTTP/1.1
...

Mà khá nhiều có ngữ nghĩa không ràng buộc; máy chủ có thể thực hiện việc xử lý yêu cầu đó theo bất kỳ cách nào nó muốn.

giả sử tôi đang nói về API JSON REST

Việc bạn không muốn sử dụng PATCH đặc biệt kỳ lạ trong trường hợp này, vì đã có các tiêu chuẩn được đề xuất cho JSON PatchJSON Merge Patch - công việc chuẩn hóa định dạng tài liệu vá có thể đã được thực hiện cho bạn.

Một lựa chọn hợp lệ khác sẽ là coi tài liệu vá là một tài nguyên riêng biệt. Về mặt ngữ nghĩa, bạn có thể tưởng tượng một cái gì đó như

PUT /014d8c83-604d-4cf0-a6ba-e1f7ef8c4898/patches/5c42c414-03c0-4ac5-af14-2b1165ac98b3 HTTP/1.1

Điều đó giúp bạn trung thực, thống nhất, ngữ nghĩa tin nhắn, hy sinh tính hợp lệ bộ đệm được chuẩn hóa .

Trong cài đặt xem xét mã, tôi sẽ từ chối một thay đổi được đề xuất nhằm xác định lại ngữ nghĩa của PUT.

HTTP không cố gắng yêu cầu các kết quả của GET phải an toàn. Những gì nó yêu cầu là ngữ nghĩa của hoạt động phải an toàn và do đó, đó là lỗi của việc triển khai, không phải giao diện hoặc người dùng giao diện đó, nếu có bất kỳ điều gì xảy ra do mất tài sản (tiền, BTW, được coi là tài sản vì lợi ích của định nghĩa này). - Fielding, 2002 .

Việc xem xét tương tự cũng đúng cho PUT; nếu việc triển khai PUT của bạn lệch khỏi ngữ nghĩa được tiêu chuẩn hóa, thì việc triển khai của bạn chịu trách nhiệm cho thiệt hại dẫn đến.

Đường dẫn tài nguyên - Tôi sử dụng GUID trong ứng dụng của mình. Kết quả là, chúng sẽ là duy nhất trên toàn cầu. Tại sao tôi cần đường dẫn tài nguyên đầy đủ, bao gồm cả tài nguyên gốc, nếu tôi chỉ có thể tham chiếu duy nhất một nguồn cung cấp phụ?

Điều đó hoàn toàn tốt. REST không quan tâm bạn sử dụng cách viết nào cho các định danh tài nguyên của bạn.

Hãy xem xét trang đích google. Bạn có cần chú ý đến cách đánh vần của URI cho hình tượng trưng ngày nay không? hoặc nơi mà hình thức tìm kiếm đang được gửi? Tất nhiên là không rồi. Tải trọng HTML bao gồm URI trong đó và khách hàng chỉ cần sử dụng các mã định danh được cung cấp, theo cách tiêu chuẩn, mà không cần phải phân tích các mã định danh đó.

Thông tin được mã hóa vào URI theo quyết định của máy chủ gốc, cho mục đích riêng của nó.

Tôi không khuyến khích sử dụng URI như vậy làm điểm vào của API của bạn. https://www.example.org/df8f5f87-15ff-4212-8fb8-4fbca2c7efcflà một chút vụng về cho tiêu dùng của con người. Một URI có thể đọc được của con người chuyển hướng đến tài nguyên UUID sẽ ổn, một URI có thể đọc được của con người trả về nội dung của tài nguyên UUID sẽ tốt hơn.

Nếu tôi POST để tạo tài nguyên mới, PUT để cập nhật hoặc XÓA để xóa, tôi muốn xem deltas trong cây, thay vì chỉ nhìn thấy tài nguyên mà tôi đã tạo / cập nhật / xóa

Điều đó tốt - một lần nữa, hãy nhìn vào tiêu chuẩn .

Tải trọng được gửi trong phản hồi 200 phụ thuộc vào phương thức yêu cầu. Đối với các phương thức được xác định bởi thông số kỹ thuật này, ý nghĩa dự định của tải trọng có thể được tóm tắt là

POST đại diện cho trạng thái hoặc kết quả thu được từ hành động

PUT, XÓA một đại diện cho trạng thái của hành động

Trong một số trường hợp, nên gửi đại diện mới của tài nguyên như một phần của phản hồi (để dành cho khách hàng độ trễ của yêu cầu / phản hồi GET) ,.


2
What's the point in using PUT then?-- Thật. Một POST sẽ hoạt động hoàn toàn tốt.
Robert Harvey

@RobertHarvey Hoặc tại sao không sử dụng PATCH? Định nghĩa phù hợp hơn.
Solomon Ucko

@SolomonUcko: Làm cho mọi thứ trở thành một POST có ưu điểm đơn giản.
Robert Harvey

3

REST là một kiểu kiến ​​trúc để thao túng tài nguyên theo cách không trạng thái (trong đó trạng thái không trạng thái có nghĩa là mỗi thao tác tự đứng vững và không phụ thuộc vào các thao tác khác có thể xảy ra).

Việc sử dụng các động từ PUT / PATCH / POST / GET / DELETE xuất phát từ việc sử dụng chung giao thức HTTP được sử dụng để chuyển và thao tác các tài nguyên. Ý nghĩa của những động từ được xác định bởi một tiêu chuẩn internet ( RFC7231 ).

Do nền tảng đó, việc sử dụng PUT của bạn là không chuẩn và có thể gây nhầm lẫn cho các nhà phát triển khác muốn sử dụng API của bạn.

Về đường dẫn tài nguyên, hầu như không ai quan tâm đến chính tả của họ (kể cả nếu tài nguyên con được liệt kê là trẻ em). Điều mọi người quan tâm là mỗi tài nguyên được xác định duy nhất. Hệ thống /parent/:pid/child/:cidthường được sử dụng khi id con chỉ là duy nhất trong một cha mẹ để vẫn có đường dẫn duy nhất trên toàn cầu đến tài nguyên.


2
Ngoài câu trả lời của Bart. Chỉ cần nhớ lại rằng người duy nhất phải đọc và hiểu URI là Máy khách HTTP và nó không quan tâm đến hệ thống phân cấp của các tài nguyên. Vì vậy, cho dù hệ thống phân cấp, mối quan hệ hay bất kỳ loại mối quan hệ nào khác của URI chỉ có ý nghĩa đối với người nghèo sống cần đọc nó
Laiv

1
  1. PUT / PATCH - Điểm vượt qua trong toàn bộ tài nguyên để sửa đổi là gì? Tôi chỉ sử dụng PUT để sửa đổi tài nguyên và tôi chỉ chuyển vào các trường tôi muốn được cập nhật. Do đó, tôi không có nhu cầu sử dụng VÒI

Dường như với tôi rằng bạn thực sự nên sử dụng PATCH như là ngữ nghĩa ở đây.

  • PUT giải thích chính xác trạng thái mong muốn. Điều này hữu ích khi tài nguyên có thể thay đổi thường xuyên và thay đổi mong muốn cần xảy ra trong một bối cảnh cụ thể.

  • PATCH giải thích một delta mong muốn cho bất cứ điều gì đang có. Điều này hữu ích khi thay đổi không quan tâm đến bối cảnh hoặc bối cảnh có liên quan nhỏ hơn rất nhiều so với toàn bộ tài nguyên.

Một hình ảnh là một ví dụ tốt là nó sẽ có ý nghĩa khi chỉ tải lên toàn bộ. Điều quan trọng là toàn bộ tài nguyên được truyền đạt để đảm bảo bối cảnh phù hợp.

Ngược lại, cập nhật số lần phát trên danh sách phát nhạc có thể có ý nghĩa tốt hơn để trở thành một đồng bằng. Không phải vì đó là một thay đổi nhỏ, mà bởi vì việc gửi lại toàn bộ danh sách có thể dễ dàng hoàn tác các thay đổi đối với nội dung của danh sách.

  1. Đường dẫn tài nguyên - Tôi sử dụng GUID trong ứng dụng của mình. Kết quả là, chúng sẽ là duy nhất trên toàn cầu. Tại sao tôi cần đường dẫn tài nguyên đầy đủ, bao gồm cả tài nguyên gốc, nếu tôi chỉ có thể tham chiếu duy nhất một nguồn cung cấp phụ?

... bắn tỉa ...

Là tất cả những gì cần thiết? Bởi vì bây giờ tôi phải xử lý lỗi bổ sung nếu đường dẫn của tôi chứa: subresourceId không thực sự thuộc sở hữu của một: childId và ditto cho một: childId không thuộc sở hữu của cha mẹ: id. Phía máy chủ của tôi đang chăm sóc ủy quyền tài nguyên. Tôi không thể chỉ tham khảo tài nguyên, chứ không phải là đường dẫn đầy đủ?

Không, bạn thực sự không cần phải sử dụng đường dẫn - bao giờ hết. Nói rằng bạn giữ tất cả các tập tin của bạn trên máy tính để bàn? Không?Tại sao không?

Có lẽ một cái gì đó để làm cho nó dễ nhìn hơn, cùng một vấn đề ở đây. GUID không cho bạn biết những gì bạn đang xử lý trong khi bạn đang thiết lập, gỡ lỗi hoặc chạy nó.

Vì vậy, những gì nó cảm thấy muốn hỗ trợ hệ thống này? hoặc để tương tác với nó? Nếu bạn chưa nghĩ đến việc này sẽ mất một chút thời gian và xem xét công việc bạn đang đẩy xuống.

Có thông tin đường dẫn rõ ràng phục vụ để xác nhận yêu cầu. Nó cũng giúp phân biệt thông tin đủ để các nhà phát triển hệ thống hỗ trợ và hạ nguồn có thể tiếp cận các url này và sử dụng chúng.

  1. Các phản ứng trở lại. Ví dụ, giả sử cấu trúc dữ liệu của tôi là một cây phân cấp, không có giới hạn thực tế về độ sâu của cây. Tài nguyên nằm ở các cấp độ khác nhau trên cây, theo kiểu phân cấp.

    a. NHẬN là rõ ràng. Nếu tôi nhận được toàn bộ cây này, tôi mong đợi toàn bộ cây là một phản hồi, với các tài nguyên được chứa trong các tài nguyên.

Bạn có thể muốn áp đặt giới hạn độ sâu, chỉ đơn giản là để một đứa trẻ thông minh không đơn giản nhận được gốc của trang web của bạn cho mọi hoạt động mà chúng có thể nghĩ ra.

b. Nếu tôi POST để tạo tài nguyên mới, PUT để cập nhật hoặc XÓA để xóa, tôi muốn xem deltas trong cây, thay vì chỉ nhìn thấy tài nguyên mà tôi đã tạo / cập nhật / xóa. Tôi không muốn phải gọi lại GET của cây mẹ sau mỗi lần POST, PUT hoặc DELETE, đặc biệt là nếu có ít thay đổi đối với cây và tôi chỉ muốn nhìn thấy vùng đồng bằng.

Nếu việc cập nhật tài nguyên đang ảnh hưởng đến cha mẹ của nó theo cách không tầm thường và có thể dự đoán được thì bạn có các vấn đề khác ... Bạn thực sự cần phải xem mô hình trạng thái và tìm hiểu tại sao thông tin lại nhảy xung quanh.

Nếu bạn chỉ muốn trả về một danh sách cụ thể của deltas, tại sao không? Tại sao không hỗ trợ một số chế độ xem đầu ra được bật bởi các tham số khác nhau? Jenkins trả về các phản hồi API của nó trong một lựa chọn xml hoặc json và cho phép bạn chỉ định một số bộ lọc để trích xuất cây con mong muốn.

Sử dụng nó cho mình

Thành thật mà nói, lùi lại từ những gì bạn đang làm và cố gắng hỗ trợ nó, hoặc tạo một ứng dụng khác để sử dụng nó (không phải là một trong những ứng dụng đã có từ trước của bạn). Làm điều gì đó tương tự cho API của bên thứ ba để bạn có một bối cảnh nền nhỏ.

Bất cứ khi nào bạn thấy mình phải làm điều gì đó không trực tiếp giải quyết yêu cầu hỗ trợ hoặc trực tiếp cần thiết cho ứng dụng khách thì API không lý tưởng và bạn biết tại sao nó ít hơn lý tưởng thậm chí còn tốt hơn, bởi vì bạn có thể sửa chữa nó hoặc không phạm sai lầm tương tự.

Ví dụ: nếu các yêu cầu cho một url nhất định liên tục thất bại, bạn phải đầu tư bao nhiêu nỗ lực để xác định điều gì đang thất bại và tại sao? Những bước bạn đã thực hiện, bạn có thể tránh được một trong những bước đó bằng cách có URI tốt hơn, hoặc ghi nhật ký tốt hơn hoặc theo dõi tốt hơn, v.v ...?

Tương tự, nếu bạn đang viết một ứng dụng khách mới, bạn cần tham khảo tài liệu bao nhiêu lần hoặc mã nguồn của API? Bạn có thể làm gì để giảm nhu cầu đó? Bạn có thể làm gì để ngăn chặn vi phạm kỳ vọng của chính bạn? Bạn có thể làm gì để đơn giản hóa vấn đề ứng dụng khách mà không khiến máy chủ trở thành ác mộng?

Đúng cách

Thẳng thắn cách đúng là hoàn cảnh. REST là một tập hợp các thực tiễn được hiển thị để hoạt động trong một số trường hợp cho một số vấn đề. Nếu vấn đề của bạn không phù hợp, vui lòng không làm cho phù hợp, nhưng sau đó cũng không yêu cầu sử dụng các thực tiễn đó.


-1

Hầu hết các tính năng của REST apis đều có vì một lý do, nhưng nó có thể không phải là lý do có liên quan đến bạn. Việc cung cấp toàn bộ tài nguyên, như trong PUT, chẳng hạn, có liên quan nếu bạn cần sự bình tĩnh, nếu không thì không. (Mặc dù tôi nghĩ rằng nó sẽ đẹp hơn đối với người dùng / đồng nghiệp / bất cứ điều gì để quảng cáo thực tế là điểm cuối của bạn không bình thường bằng cách sử dụng POST hoặc PATCH thay thế.)

Đối với con đường điều tôi chưa bao giờ nghe nói rằng có liên quan đến nghỉ ngơi. /root/345dd4dc-e175-455f-b545-85b1b1ce3e82là một phần của cây như /foo/bar/baz. Có thể một chút ít thân thiện với người dùng nhưng không kém phần yên tĩnh như tôi có thể thấy.

Nếu bạn muốn lý luận chi tiết hơn về lý do tại sao REST được thiết kế như tôi nghĩ bạn nên đọc luận văn gốc: https://www.ics.uci.edu/~fielding/pub/dissertation/fielding_dissertation.pdf

Đọc rằng bạn có thể phát hiện ra rằng nó hoàn toàn khác với cách REST được thể hiện trong các cuộc hội thoại hoặc được sử dụng trong API ngày nay. Rõ ràng rất nhiều người khác đã tìm thấy lý do, tốt hay xấu, để rời khỏi nó.

Tôi đặc biệt thích trích dẫn này mà bạn có thể tìm thấy có liên quan:

HTTP không được thiết kế để trở thành một giao thức vận chuyển. Nó là một giao thức chuyển giao trong đó các thông báo phản ánh ngữ nghĩa của kiến ​​trúc Web bằng cách thực hiện các hành động trên các tài nguyên thông qua việc chuyển và thao tác biểu diễn các tài nguyên đó. Có thể đạt được một loạt các chức năng bằng giao diện rất đơn giản này, nhưng theo giao diện là bắt buộc để ngữ nghĩa HTTP vẫn hiển thị cho các trung gian. Đó là lý do tại sao HTTP đi qua tường lửa. Hầu hết các tiện ích mở rộng được đề xuất gần đây cho HTTP, ngoài WebDAV [60], chỉ đơn thuần sử dụng HTTP như một cách để di chuyển các giao thức ứng dụng khác thông qua tường lửa, đây là một ý tưởng sai lầm cơ bản. Nó không chỉ đánh bại mục đích có tường lửa, nhưng nó sẽ không hoạt động lâu dài vì các nhà cung cấp tường lửa đơn giản sẽ phải thực hiện lọc giao thức bổ sung. Do đó, sẽ không có ý nghĩa gì khi thực hiện các tiện ích mở rộng đó trên HTTP, vì điều duy nhất HTTP hoàn thành trong tình huống đó là thêm chi phí từ một cú pháp cũ. Một ứng dụng thực sự của HTTP ánh xạ các hành động của người sử dụng giao thức sang một thứ có thể được thể hiện bằng ngữ nghĩa HTTP, do đó tạo ra API dựa trên mạng cho các dịch vụ mà các tác nhân và trung gian có thể hiểu được mà không cần biết về ứng dụng.


2
"Mặc dù tôi nghĩ rằng nó sẽ đẹp hơn đối với người dùng / đồng nghiệp / bất cứ điều gì để quảng cáo thực tế là điểm cuối của bạn không bình thường bằng cách sử dụng POST hoặc PATCH thay thế." - Đây không phải là một câu hỏi hay. Các phương thức HTTP có ngữ nghĩa được xác định chính xác và toàn bộ cơ sở hạ tầng web trên toàn thế giới phụ thuộc vào các ngữ nghĩa đó. Ví dụ: proxy có thể thử lại PUTyêu cầu nhiều lần mà bạn không biết và họ được phép làm điều đó vì thông số HTTP nói rằng đó PUTlà idempotent . Nếu PUTs của bạn không bình thường, thì điều này sẽ phá vỡ dịch vụ của bạn .
Jörg W Mittag

2
Trong một thời gian, "máy gia tốc web" là tất cả những cơn thịnh nộ, và trên thực tế, chúng đang trở lại cho các thiết bị di động. Những máy gia tốc này đã tìm nạp trước và lưu trữ tài nguyên và họ được phép làm điều đó, bởi vì thông số HTTP đảm bảo rằng GETvà hoàn HEADtoàn không có tác dụng phụ. Một số người bị mất dữ liệu, vì họ đang sử dụng các ứng dụng web được thiết kế tồi, trong đó việc xóa nội dung được thực hiện với một GETyêu cầu và trình tăng tốc web vui vẻ gửi GETyêu cầu tới tất cả các URI mà nó có thể tìm thấy.
Jörg W Mittag

Bạn đúng tất nhiên. Tôi không thể làm việc với bất kỳ sự nhiệt tình nào về một trang web hoạt động đúng nữa. Cảm giác như một trận chiến thua với tôi, nhưng có lẽ bạn đang ở trong một môi trường đẹp hơn, nơi những thứ như thế này thực sự hoạt động. Nơi tôi là http chỉ là một phương tiện giao thông với phần bổ sung mà nó có thể gỡ lỗi từ trình duyệt thay vì netcat, và đó là tất cả.
monocell
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.