Chém dấu gạch chéo trong API RESTful


60

Tôi đã có một cuộc tranh luận về việc phải làm gì với dấu gạch chéo trong API RESTful.

Hãy nói rằng tôi có một tài nguyên được gọi là chó và tài nguyên cấp dưới cho từng con chó. Do đó chúng ta có thể làm như sau:

GET/PUT/POST/DELETE http://example.com/dogs
GET/PUT/POST/DELETE http://example.com/dogs/{id}

Nhưng chúng ta phải làm gì với trường hợp đặc biệt sau:

GET/PUT/POST/DELETE http://example.com/dogs/

Quan điểm cá nhân của tôi là điều này nói rằng hãy gửi yêu cầu đến một tài nguyên chó riêng lẻ với id = null. Tôi nghĩ rằng API sẽ trả về 404 cho trường hợp này.

Những người khác nói rằng yêu cầu đang truy cập vào tài nguyên chó, tức là dấu gạch chéo bị bỏ qua.

Có ai biết câu trả lời dứt khoát không?


2
Tôi nghĩ cách RESTful là phân biệt chó / id và chó (có nghĩa là tất cả chó).
pdr

Từ cuốn sách Dịch vụ web RESTful - tài nguyên cấp dưới: tài nguyên tồn tại liên quan đến một số tài nguyên khác của mẹ cha tức là chó / {id} Cơ sở dữ liệu hỗ trợ web có thể hiển thị bảng dưới dạng tài nguyên và các hàng cơ sở dữ liệu riêng lẻ dưới dạng tài nguyên phụ của nó .
Gaz_Edge

Nó đang truy cập vào tài nguyên chó, dấu gạch chéo nên được bỏ qua, điều đó có nghĩa là nó sẽ nhận được phản hồi bị cấm vì cố gắng xóa thứ gì đó không nên áp dụng. Tôi đoán rằng 404 cũng được chấp nhận. Có vấn đề gì không?
Benjamin Gruenbaum

Tôi không theo dõi - ai nói bạn không thể xóa chó? Nếu bạn xóa chó, nó sẽ tự xóa và tất cả các con chó riêng lẻ. Đó là lý do tại sao tôi nghĩ cho phép gọi chó / là rủi ro. Điều gì xảy ra nếu khách hàng có ý định xóa một con chó riêng lẻ, nhưng vô tình bỏ đi {id}. Kết quả là tất cả những con chó sẽ bị xóa. An toàn hơn nhiều khi cho rằng nó đang yêu cầu {id} null và trả về 404
Gaz_Edge

Tôi sẽ đối xử dogsdogs/tương đương. Đối với tôi rõ ràng đó dogs/là một thư mục chứa các con chó riêng lẻ. Nó không rõ ràng dogslà gì , nhưng tôi coi nó là tương đương, giống như hầu hết các máy chủ web chấp nhận truy cập vào các thư mục mà không có dấu vết /.
CodeInChaos

Câu trả lời:


50

Không ai trong số này là có thẩm quyền (vì REST không có ý nghĩa chính xác). Nhưng từ bài báo gốc về REST, một URL đầy đủ (không kết thúc bằng /) đặt tên cho một tài nguyên, trong khi một tài khoản kết thúc bằng dấu gạch chéo '/' là một nhóm tài nguyên (có thể không được diễn đạt như vậy).

NHẬN một URL có dấu gạch chéo ở cuối được cho là liệt kê các tài nguyên có sẵn.

GET http://example.com/dogs/          /* List all the dogs resources */

Một PUT trên một URL bằng dấu gạch chéo được cho là để thay thế tất cả các tài nguyên.

PUT http://example.com/dogs/          /* Replace all the dogs resources */

XÓA trên một URL có dấu gạch chéo được cho là xóa tất cả các tài nguyên

DELETE http://example.com/dogs/       /* Deletes all the dogs resources */

POST trên URL có dấu gạch chéo được cho là tạo tài nguyên mới sau đó có thể được truy cập. Để phù hợp với tài nguyên mới nên có trong thư mục này (mặc dù rất nhiều kiến ​​trúc RESTful gian lận ở đây).

POST http://example.com/dogs/        /* Creates a new dogs resource (notice singular) */

Vân vân.

Trang wiki về chủ đề này dường như giải thích rõ về nó:

Xem ví dụ https://en.wikipedia.org/wiki/Repftimeatic_state_transfer#Applied_to_Web_service .


Nó cũng phù hợp với mô hình đường dẫn / url bình thường, trong đó các thư mục thường được viết bằng dấu/
CodeInChaos

4
Vì vậy, điều gì sẽ xảy ra nếu bạn truy cập vào một nhóm tài nguyên mà không có dấu vết /?
oberlies

1
@oberlies: Nó phụ thuộc vào ngữ cảnh. Không có quy tắc cứng và nhanh chỉ thực hành tốt nhất. Luôn luôn có những quy tắc cho quy tắc và nó có nghĩa là những gì bạn mong đợi nó có nghĩa. Trong ví dụ trên: GET http://example.com/dogscó thể trả về thông tin meta về những con chó (không phải chính danh sách mà là thông tin meta về danh sách những con chó). Có thể hoặc có thể đó là một lỗi.
Martin York

1
As the last character within a URI’s path, a forward slash (/) adds no semantic value and may cause confusion. It’s better to drop them completely.Đây không phải là nơi duy nhất đề nghị không sử dụng dấu gạch chéo đào tạo
Laiv

@Laiv Tôi không đồng ý với tình cảm. Nhưng vui lòng liên kết một tài liệu tham khảo có thẩm quyền hơn (đó là một liên kết yếu).
Martin York

17
Does anyone know the definitive answer?

Không có tài liệu nào vì không có tài liệu chính thức về những gì cần thiết để dịch vụ được coi là RESTful.

Điều đó nói rằng tôi sẽ cho phép dấu gạch chéo đơn giản để dễ sử dụng. Trong khi về mặt kỹ thuật, điều này có thể được coi là cố gắng truy cập một con chó với ID null; Tôi không thấy người dùng thực hiện bước nhảy này trừ khi họ đã đọc nó trong tài liệu của bạn. Tôi có thể thấy một người dùng đang cố viết mã chống lại API của bạn và bao gồm dấu gạch chéo đơn giản từ thói quen và tự hỏi tại sao họ nhận được phản hồi 404 khi họ muốn có một danh sách chó.


Điều gì về DELETE example.com/dogs ?
Benjamin Gruenbaum

vì chó là cha mẹ của tất cả các con chó riêng lẻ, việc xóa chó sẽ xóa tất cả các con chó riêng lẻ và chính nó. Nếu bạn không làm điều đó, hypermedia của bạn sẽ bị hỏng
Gaz_Edge

@Gaz_Edge: Trong REST example.com/dogslà một tài nguyên hoàn toàn độc lập với bất kỳ tài nguyên nào example.com/dogs/X. Do đó, một XÓA trên example.com/dogskhông phải xóa tất cả các con chó / * (mặc dù nó có thể nếu đó là ngữ nghĩa). Nhưng XÓA example.com/dogs/nên xóa tất cả những con chó / *.
Martin York

3
Tôi sẽ nói một lần nữa rằng vì không có một bộ quy tắc dứt khoát nào về RESTful, điều gì sẽ xảy ra khi bạn XÓA / chó hoặc / chó / sẽ dựa trên những gì bạn mong đợi người tiêu dùng API của bạn mong đợi. Có khả năng là họ thực sự muốn xóa tất cả những con chó chỉ với một yêu cầu? Nếu vậy thì hãy thực hiện nó như thế, nếu không thì hãy trả lời 405 Phương thức Không được phép.
Mike

1
Tôi biết đây là một chủ đề cũ, nhưng gần đây tôi đã tự hỏi về điều này. Đối với những gì nó có giá trị, các OS X xử lý Bash shell foo, foo/foo////hệt. Về cơ bản, nó dường như loại bỏ các đoạn đường trống. Vì vậy, nếu bạn làm theo cách tiếp cận tương tự với dịch vụ REST của bạn dogsdogs/sẽ đề cập đến điều tương tự.
Greg Brown

2

Hai lối.

Phương pháp 1

Luôn sử dụng dấu gạch chéo cho bất kỳ tài nguyên nào có thể chứa trẻ em.

Chỉ cần xem xét "NHẬN" trên thư mục public_html với các tệp.

Không thể khi hello.html là một tệp:

/hello.html
/hello.html/youagain.html

Nhưng có thể khi hello.html là một thư mục:

/hello.html/     (actually /hello.html/index.html)
/hello.html/youagain.html

Vì vậy, nếu "hello.html" có thể có con thì luôn luôn và mãi mãi "/hello.html/" và "/hello.html/index.html" (hoặc đơn giản là /hello.html/) là danh sách những đứa trẻ này .

Phương pháp 2

Hãy "thông minh".

$ find
.
./hello.html
./hello.html/index.html

Lệnh find không quan tâm đến loại hello.html. Thư mục hoặc tập tin, ai quan tâm, đó là tên của một đối tượng. Khi chúng tôi viết "cp youagain.html hello.html", cp có thể tìm ra cách xử lý hello.html. cp là thông minh. Máy chủ web của bạn cũng thông minh. Nó có một thư viện xử lý đường dẫn. Nó có định tuyến. Nó có thể stat và cho bạn biết nếu một tên là một đối tượng hoặc một thư mục. Nó có thể chuyển hướng blah sang blah / hoặc thậm chí chỉ phục vụ cùng một phản hồi cho cả hai. Điều này thật tuyệt vời !!! đường. Quá nhiều công nghệ. Ai đã từng muốn đơn giản nối các chuỗi đường dẫn khi chúng ta có thể làm tất cả điều đó ???

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.