Quy ước REST URI - Tên số ít hoặc số nhiều của tài nguyên trong khi tạo tài nguyên


529

Tôi mới sử dụng REST và tôi đã quan sát thấy rằng trong một số dịch vụ RESTful, họ sử dụng URI tài nguyên khác nhau để cập nhật / nhận / xóa và Tạo. Nhu la

  • Tạo - sử dụng / tài nguyên với phương thức POST (quan sát số nhiều) tại một số nơi sử dụng / resource (số ít)
  • Cập nhật - sử dụng / resource / 123 với phương thức PUT
  • Nhận - Sử dụng / resource / 123 với phương thức GET

Tôi hơi bối rối về quy ước đặt tên URI này. Chúng ta nên sử dụng số nhiều hay số ít để tạo tài nguyên? Điều gì nên là tiêu chí trong khi quyết định đó?


9
Theo chủ đề này, tôi đã thu thập một vài ví dụ về API REST nổi tiếng trong một bài viết: inmensosofa.blogspot.com/2011/10/ .
jjmontes

3
Kết luận tôi đạt được sau khi đọc tất cả các câu trả lời dưới đây: Luôn sử dụng số ít vì (a) nó nhất quán, (b) nó ánh xạ trực tiếp đến tên số ít và tên bảng, (c) một số danh từ số nhiều không đều (không thể đoán trước) trong tiếng Anh
Will Sheppard

Xem câu trả lời này để biết liên kết đến các quy ước đặt tên bảng số ít và có một bài viết khác đề cập đến vấn đề chính xác này Vấn đề nan giải của Rest API Developer - cảm ơn bạn @Sorter
Will Sheppard

Câu trả lời:


281

Tiền đề của việc sử dụng /resourceslà nó đại diện cho tài nguyên "tất cả". Nếu bạn làm một GET /resources, bạn có thể sẽ trả lại toàn bộ bộ sưu tập. Bằng cách gửi đến /resources, bạn đang thêm vào bộ sưu tập.

Tuy nhiên, các tài nguyên riêng lẻ có sẵn tại / resource. Nếu bạn làm một GET /resource, bạn có thể sẽ gặp lỗi, vì yêu cầu này không có ý nghĩa gì, trong khi lại /resource/123có ý nghĩa hoàn hảo.

Sử dụng /resourcethay vì /resourceslà tương tự như cách bạn sẽ làm điều này nếu bạn đang làm việc với, chẳng hạn, một hệ thống tập tin và một bộ sưu tập các tập tin và /resourcelà "thư mục" với các cá nhân 123, 456tập tin trong nó.

Không có cách nào là đúng hay sai, hãy đi với những gì bạn thích nhất.


55
Câu trả lời chính xác! Nhưng các thư mục "mặc định" trong Windows có tên số nhiều . Như "Tệp chương trình", "Người dùng", "Tài liệu", "Video", v.v. Ngoài ra, tôi đã gặp các tên số nhiều trong các trang web thường xuyên hơn nhiều.
Dmitry Gonchar

50
quy ước defacto hầu hết mọi người và API ngoài kia đang giữ nó ở dạng số nhiều mọi lúc. Id chỉ định MỘT ô tô tài nguyên / id
positiveGuy

205
"Không có cách nào là đúng hay sai, hãy đi với những gì bạn thích nhất.". Ah dòng nổi tiếng tôi nghe rất thường xuyên và bị bệnh và mệt mỏi khi nghe từ mọi người. Các quy ước quan trọng và NÊN được tranh luận một cách xây dựng giữa cộng đồng, đó là nơi các giải pháp tốt hơn xuất hiện và các thực tiễn tốt. Khi bạn đang sử dụng cả số nhiều và số ít cho tên tài nguyên trong URI, điều đó làm phức tạp mã của bạn và API vì người dùng và mã đằng sau API phải tính đến điều đó trong các tuyến và logic để phân biệt đơn và số nhiều trong khi bạn chỉ cần dán với số nhiều tất cả thời gian bạn không có vấn đề.
Tích cực,

30
@TomaszPluskiewicz Bạn hoàn toàn đúng khi khách hàng không quan tâm. Là nhà phát triển phần mềm, chúng ta nên quan tâm - và tôi đồng ý với nhận xét của WTF rằng các cuộc tranh luận mang tính xây dựng về quy ước là có giá trị.
Travis D

12
Vì vậy, ai đó có thể chỉ cần trả lời một từ và chấp nhận nó để tôi không phải đọc tất cả (một lần nữa).
Ben George

623

Đối với tôi tốt hơn là có một lược đồ mà bạn có thể ánh xạ trực tiếp tới mã (dễ tự động hóa), chủ yếu vì mã là thứ sẽ có ở cả hai đầu.

GET  /orders          <---> orders 
POST /orders          <---> orders.push(data)
GET  /orders/1        <---> orders[1]
PUT  /orders/1        <---> orders[1] = data
GET  /orders/1/lines  <---> orders[1].lines
POST /orders/1/lines  <---> orders[1].lines.push(data) 

22
Khó khăn hay dễ dàng của điều này là do không tôn trọng HATEOS. Nó không quan trọng cho dù đó là số nhiều hay số ít hay bất cứ điều gì khác. Bạn nên tôn trọng các uri được gửi từ máy chủ và không "xây dựng" các uri của bạn trên máy khách. Sau đó, bạn có 0 ánh xạ để làm cho mã của bạn.
Richard

7
@richard Khách hàng vẫn phải thực hiện ánh xạ. Trong HATEOS, họ sẽ phải ánh xạ tới một tên đại diện cho mối quan hệ (rel) với cấu trúc URI. Rel, phương thức (động từ) và Content-Type sau đó tạo nên phương tiện tài nguyên. Điều này không loại trừ sự cần thiết phải có một thiết kế URI tốt. Mặc dù ứng dụng khách có thể được ưu tiên cho tên rel, các nhà phát triển API vẫn cần một tiêu chuẩn dễ đọc cho con người để xây dựng URI.

4
Đây là một câu trả lời tốt hơn theo ý kiến ​​của tôi. Ngoại trừ việc tôi luôn thích sử dụng số ít thay vì số nhiều. User.getList (), User.getById, User.delete, v.v.
Đông Monk

3
Tôi thích sự đơn giản. Bản đồ cũng có lợi ích của việc tạo tài liệu và kiểm tra trên các tuyến đường cực kỳ dễ viết.
delos

5
Điều này có ý nghĩa với tôi. Tuy nhiên, chúng tôi là cửa hàng đầu tiên về cơ sở dữ liệu, nghĩa là chúng tôi tạo mã và các thực thể api từ lược đồ cơ sở dữ liệu của chúng tôi. Và các tiêu chuẩn cơ sở dữ liệu có xu hướng ủng hộ các tên bảng số ít, vì vậy chúng tôi sẽ làm theo điều đó, nhưng vẫn theo cùng một logic như câu trả lời này.
André C. Andersen

274

Tôi cũng không thấy điểm nào trong việc này và tôi nghĩ đó không phải là thiết kế URI tốt nhất. Là người dùng dịch vụ RESTful, tôi mong muốn tài nguyên danh sách có cùng tên cho dù tôi có truy cập danh sách hoặc tài nguyên cụ thể 'trong' danh sách. Bạn nên sử dụng cùng một mã định danh cho dù bạn muốn sử dụng tài nguyên danh sách hay tài nguyên cụ thể.


69
Đây là câu trả lời tốt nhất theo như tôi nghĩ. Tôi đánh giá cao các nhà thiết kế API thích tính chính xác về ngôn ngữ khi nói "lấy tài nguyên # 123", nhưng đó là rắc rối mã hóa thêm khi viết các ứng dụng khách của API cũng như tài liệu trợ giúp. (GET / api / people so với GET / api / person / 123? Euuuchh.) .... thay vì nghĩ về nó như "lấy tài nguyên # 123", hãy diễn đạt nó trong đầu như "lấy từ bộ sưu tập tài nguyên mà khớp với số 123 ".
Warren Rumak

5
Phân biệt tài nguyên số nhiều / số ít không phải là về tính chính xác ngôn ngữ mà là về quy mô. / staff / 12 đọc cho tôi dưới dạng tập hợp con của tài nguyên nhân viên với id '12' (nó có thể có nghĩa là bất cứ điều gì, ví dụ như một truy vấn tìm kiếm đã lưu trên các nhân viên bị sa thải gần đây). Nếu bạn đọc ở trên với tư cách là nhân viên có id '12', bạn sẽ đại diện cho tập hợp con như thế nào? Tùy chọn duy nhất là bằng cách tạo ra các bộ sưu tập phân biệt quặng phức tạp hơn của URI chứa các đối tượng từ chính các đối tượng (ví dụ số ít so với số nhiều).
Erik

9
Chọn / nhân viên / 12 để thể hiện một truy vấn tìm kiếm trên các nhân viên bị sa thải gần đây (hoặc bất kỳ tập hợp con nào) sẽ là thiết kế tồi. Nếu bạn muốn đại diện cho các tập hợp con dưới bất kỳ hình thức nào hơn tôi đề nghị giới thiệu chúng dưới dạng tài nguyên (có tên riêng) theo cách riêng của chúng.
Jan Deinhard

3
Điều này không có gì để làm với sự dễ hiểu cho khách hàng. Đó là về việc giải quyết những thứ khác nhau bằng các URL khác nhau. Và có thể đáp ứng tất cả các phương thức HTTP mà không bị xung đột. Bạn có thể có một tài nguyên là một tập hợp các mục và một tài nguyên đại diện cho chính một mục đó. Đối với tất cả tôi quan tâm, tài nguyên bộ sưu tập có thể là example.org/166316e2-e1 và một mục cụ thể trong bộ sưu tập đó example.org/20d68348-ccc-001c4200de . Khách hàng không nên tạo URL (rõ ràng là không có tỷ lệ, đó không phải là RESTful và đó là loại quan hệ liên kết dành cho).
Erik

4
Nếu bạn không nghĩ rằng các URL tùy ý là đẹp, hãy thoải mái xác định tài nguyên bộ sưu tập với tên số nhiều và một mục riêng lẻ với một tên số ít. Nếu bạn không thích URL tiếng Anh và ngôn ngữ tự nhiên của bạn không hỗ trợ cách viết ký hiệu số nhiều / số nhiều, hãy sử dụng từ khác để định nghĩa nó bằng ngôn ngữ ưa thích của bạn, tôi cho rằng tất cả các ngôn ngữ cho phép bạn phân biệt bằng cách nào đó '/ the-sưu tập-of- bla / 2321 'so với' bla / 61 'bằng văn bản. Và mỗi tài nguyên trong hai tài nguyên khác nhau đó thể hiện kết quả hoàn toàn khác nhau khi gửi GET / PUT / DELETE / POST / PATCH và các tài nguyên khác.
Erik

77

Số nhiều

  • Đơn giản - tất cả các url bắt đầu với cùng một tiền tố
  • Hợp lý - orders/có được một danh sách chỉ mục của các đơn đặt hàng.
  • Tiêu chuẩn - Tiêu chuẩn được áp dụng rộng rãi nhất theo sau là phần lớn các API công khai và riêng tư.

Ví dụ:

GET /resources - trả về một danh sách các mục tài nguyên

POST /resources - tạo một hoặc nhiều mục tài nguyên

PUT /resources - cập nhật một hoặc nhiều mục tài nguyên

PATCH /resources - cập nhật một phần một hoặc nhiều mục tài nguyên

DELETE /resources - xóa tất cả các mục tài nguyên

Và đối với các mục tài nguyên đơn lẻ:

GET /resources/:id- trả về một mục tài nguyên cụ thể dựa trên :idtham số

POST /resources/:id - tạo một mục tài nguyên với id được chỉ định (yêu cầu xác thực)

PUT /resources/:id - cập nhật một mục tài nguyên cụ thể

PATCH /resources/:id - cập nhật một phần một mục tài nguyên cụ thể

DELETE /resources/:id - xóa một mục tài nguyên cụ thể

Đối với những người ủng hộ số ít, hãy nghĩ về nó theo cách này: Bạn sẽ hỏi ai đó về một orderđiều gì đó và mong đợi một điều, hoặc một danh sách các điều? Vậy tại sao bạn mong đợi một dịch vụ trả về một danh sách những thứ khi bạn gõ /order?


10
Số ít : Trong trường hợp, khi một phần trong hệ thống của bạn chỉ có một đối tượng (0-1, có tồn tại hay không), ví dụ: người dùng / 1 / avatar, bạn có thể sử dụng dạng số ít để gắn nhãn cho đối tượng này (ví dụ: avatar) - ví dụ chi tiết hơn ở đây: stackoverflow .com / a / 38296217/860099 . BTW - câu trả lời rất hay :)
Kamil Kiełczewski

Điều gì về ánh xạ tới tên lớp và tên bảng, nên là số ít? (xem câu trả lời khác )
Will Sheppard

@WillSheppard - Tên lớp là tốt nhất ở dạng số ít và tên bảng là tốt nhất ở dạng số nhiều. Ví dụ, Ordermột tên hay cho một lớp liên quan đến các thể hiện đơn lẻ của các đối tượng đề cập đến một đơn hàng. OrderListlà tên của một lớp liên quan đến nhiều Ordertrường hợp. Orders Tablelà một tên tốt cho một bảng cơ sở dữ liệu của nhiều đơn đặt hàng.
Eric Knudtson

Tôi muốn NHẬN / đơn đặt hàng nhưng tôi chỉ muốn / 1
jim smith

@ jim-smith thì tại sao bạn không yêu cầu / 1 từ bộ sưu tập người dùng có GET / users / 1?
Rohmer

49

Số ít

Thuận tiện Mọi thứ có thể có tên số nhiều bất thường. Đôi khi họ không có. Nhưng tên Singular luôn ở đó.

ví dụ: Khách hàng Địa chỉ đối với Khách hàng Địa chỉ

Hãy xem xét tài nguyên liên quan này.

Điều này /order/12/orderdetail/12dễ đọc và hợp lý hơn /orders/12/orderdetails/4.

Bảng cơ sở dữ liệu

Một tài nguyên đại diện cho một thực thể như một bảng cơ sở dữ liệu. Nó nên có một tên số ít logic. Đây là câu trả lời trên tên bảng.

Ánh xạ lớp

Các lớp học luôn luôn là số ít. Các công cụ ORM tạo các bảng có cùng tên với tên lớp. Khi ngày càng có nhiều công cụ được sử dụng, các tên số ít đang trở thành một tiêu chuẩn.

Đọc thêm về Thế lưỡng nan của Nhà phát triển API REST


39
Tên số ít luôn ở đó /clothe/12/trouser/34 :)
Gert Arnold

18
@GertArnold từ clothelà một động từ. Các API còn lại thường bám sát các danh từ khi nói về tài nguyên và sử dụng các động từ khi mô tả các hành động. Các hình thức số ít là clout, nhưng là cổ xưa và có thể sẽ được thay thế phù hợp hơn garment.
Steve Buzonas

@SteveBuzonas Và cho quần tây và kính râm?
Koray Tugay

32

Trong khi thực tiễn phổ biến nhất là apis RESTful trong đó số nhiều được sử dụng /api/resources/123, ví dụ , có một trường hợp đặc biệt khi tôi thấy việc sử dụng một tên số ít thích hợp / biểu cảm hơn tên số nhiều. Đó là trường hợp của mối quan hệ một-một. Cụ thể nếu mục tiêu là một đối tượng giá trị (trong mô hình thiết kế hướng theo miền).

Chúng ta hãy giả sử rằng mọi tài nguyên đều có một accessLogcó thể được mô hình hóa thành một đối tượng giá trị, tức là không phải là một thực thể do đó không có ID. Nó có thể được thể hiện như /api/resources/123/accessLog. Các động từ thông thường (POST, PUT, DELETE, GET) sẽ thể hiện một cách thích hợp ý định và thực tế là mối quan hệ thực sự là một đối một.


4
Cố gắng tốt đẹp. Nhưng nó sẽ tốt hơn là "accessLogEntries". :-)
Tom Russell

8
@TomRussell tại sao? Ý nghĩa của việc này rất quan trọng. Tôi hiểu lý do tại sao bạn sẽ sử dụng số nhiều ngay cả khi bạn truy cập tài nguyên bằng mã định danh, nhưng đối với nhiều người hoặc một người thì điều đó khá sai lệch. Hãy xem xét một api quản lý nhân viên cho một công ty đa địa điểm. Mỗi nhân viên làm việc tại một địa điểm. GET /users/123/locationnên tìm nạp vị trí mà người dùng làm việc tại. Không GET /users/123/locationsthực sự gây hiểu lầm như một người tiêu dùng?
Carrie Kendall

1
@CarrieKendall Tôi thấy quan điểm của bạn. Vì accessLogđược mô hình hóa như một thuộc tính hoặc giá trị, chứ không phải là một thực thể nên nó là số ít. Nếu bạn được trao cho kỹ thuật quá mức, thì một mục nhật ký sẽ là một thực thể và bạn có /api/accessLogEntries?resource=123.
Tom Russell

Đồng ý, mặc dù, tôi nghĩ rằng nó phá vỡ quy ước của số nhiều. Đó là một khó khăn. Đối với tôi, điều quan trọng hơn là API phải đơn giản, tức là tài liệu nên khen ngợi việc triển khai đơn giản.
Carrie Kendall

Tôi là một lập trình viên hơn là một người hệ thống hoặc cơ sở dữ liệu nên tôi thích một API kể một câu chuyện hơn là tuân thủ quy ước. Các ý nghĩa cho tài liệu tự động là có thật, mặc dù.
Tom Russell

26

Tại sao không theo xu hướng phổ biến của tên bảng cơ sở dữ liệu, trong đó một hình thức số ít thường được chấp nhận? Ở đó, làm điều đó - hãy tái sử dụng.

Bảng đặt tên tiến thoái lưỡng nan: Tên số ít so với số nhiều


8
Das Auto là cách tốt hơn so với Die Autos. Ngoài ra, quy ước số nhiều tiếng Anh không nhất quán.
FlavorScape

7
Không gian tên tài nguyên là một vấn đề ngữ nghĩa, không thực hiện. Vì vậy, sử dụng các bảng tương tự DB, không may mắn lắm. Ngoài ra khi làm việc với DB-s bạn đang thao tác chỉ bảng, mặc dù tất nhiên bạn có thể ảnh hưởng đến nội dung (hàng), nhưng trong REST không có ràng buộc để thao tác một đơn tài nguyên trực tiếp.
arpadf

3
Tôi nghĩ rằng đây là một sự tương tự tốt, nhưng quan trọng hơn là quyết định nên đi số ít hay số nhiều là phù hợp với bất cứ điều gì bạn chọn. Bạn sẽ không chèn vào Người dùng và sau đó chọn từ Người dùng. Cùng một quy tắc nên áp dụng cho tài nguyên REST - không đổi tên chúng tùy thuộc vào những gì bạn đang làm.
Todd Menier 3/03/2015

3
Nó không chỉ là tên bảng, nó còn có thể so sánh với tên lớp trong OO (lớp của tôi sẽ được gọi là Khách hàng không phải Khách hàng).
bytedev

Trong trường hợp này, ngữ nghĩa là quá quan trọng để đơn giản chấp nhận các xu hướng "đã được xác định"
Cattani Simone

19

Tôi ngạc nhiên khi thấy rằng rất nhiều người sẽ nhảy vào bandwagon danh từ số nhiều. Khi thực hiện chuyển đổi số ít sang số nhiều, bạn có quan tâm đến danh từ số nhiều không đều? Bạn có thích đau không?

Xem http://web2.uvcs.uvic.ca/elc/studyzone/330/grammar/irrplu.htmlm

Có nhiều loại số nhiều không đều, nhưng đây là những loại phổ biến nhất:

Loại danh từ Hình thành ví dụ số nhiều

Ends with -fe   Change f to v then Add -s   
    knife   knives 
    life   lives 
    wife   wives
Ends with -f    Change f to v then Add -es  
    half   halves 
    wolf   wolves
    loaf   loaves
Ends with -o    Add -es 
    potato   potatoes
    tomato   tomatoes
    volcano   volcanoes
Ends with -us   Change -us to -i    
    cactus   cacti
    nucleus   nuclei
    focus   foci
Ends with -is   Change -is to -es   
    analysis   analyses
    crisis   crises
    thesis   theses
Ends with -on   Change -on to -a    
    phenomenon   phenomena
    criterion   criteria
ALL KINDS   Change the vowel or Change the word or Add a different ending   
     man   men
     foot   feet
     child   children
     person   people
     tooth   teeth
     mouse   mice
 Unchanging Singular and plural are the same    
     sheep deer fish (sometimes)

5
Tôi không hiểu mối quan tâm ở đây. Chúng tôi không phải thay đổi số ít sang số nhiều theo chương trình. Hầu hết các hình thức số nhiều ở trên là nổi tiếng, và không nên là một mối quan tâm. Nếu ai đó có kiến ​​thức tiếng Anh kém, anh ta sẽ đánh vần bất kỳ phần nào trong biến của bạn không chính xác. Ngoài ra, theo logic của bạn, bạn có khuyên bạn nên sử dụng các hình thức số ít để giới thiệu các bộ sưu tập trong mã nguồn không?
kishor borat

1
Có những từ tiếng Anh không đều đến mức thường là một vấn đề ngay cả trong Anglosphere và chúng là những thuật ngữ thường được sử dụng như chỉ mục / chỉ mục / chỉ số, đỉnh / đỉnh / đỉnh, ma trận / ma trận / ma trận, bán kính / bán kính / radii, v.v ... Tôi không thấy điểm nào trong việc tạo các đường dẫn REST ở dạng số nhiều, bởi vì nếu tất cả chúng đều là số ít, thì mọi thứ sẽ rõ ràng hơn.
chết tiệt

@kishorborate, Sử dụng số nhiều làm URI dễ bị lỗi hơn, ngay cả đối với người nói tiếng Anh bản ngữ. Như damd chỉ ra, số nhiều như chỉ số / chỉ mục / chỉ số đang giới thiệu nhiều vấn đề hơn. Và có những danh từ không đếm được. Trộn các danh từ không đếm được với số nhiều là một vấn đề khác. Tại sao làm cho các lập trình viên khó dành nhiều thời gian hơn cho những điều này? Tôi đề nghị sử dụng thông báo cho tất cả mọi thứ. Nếu có / {id}, thì API sẽ trả về một bản ghi. Nếu không có / {id} theo sau, thì API sẽ trả về bộ sưu tập.
Đập Fu

3
@DamingFu Tài nguyên số ít có thể không phải lúc nào cũng có id liên quan đến nó. ví dụ. / user / {id} / nickName Bằng cách nhìn vào nó, không rõ, liệu nó sẽ trả về danh sách nickNames hay nickName đơn? Do đó, API trực quan hơn khi sử dụng các dạng số nhiều. Có, vài từ sẽ có dạng số nhiều không đều. Đối với một người đang đọc dạng số nhiều, không phải là một vấn đề. Nó chỉ phát hành khi viết chữ ký API. Nhưng tần suất của những từ như vậy không cao, ngoài ra, việc tìm dạng số nhiều của bất kỳ từ nào cũng không tốn thời gian. Chúng ta nên chấp nhận đánh đổi, để làm cho API trực quan hơn.
kishor bated

15

Từ quan điểm của người tiêu dùng API, các điểm cuối sẽ có thể dự đoán được vì vậy

Lý tưởng nhất là ...

  1. GET /resources nên trả về một danh sách các tài nguyên.
  2. GET /resource nên trả về mã trạng thái 400 cấp.
  3. GET /resources/id/{resourceId} sẽ trả về một bộ sưu tập với một tài nguyên.
  4. GET /resource/id/{resourceId} nên trả về một đối tượng tài nguyên.
  5. POST /resources Nên tạo tài nguyên hàng loạt.
  6. POST /resource nên tạo một nguồn lực.
  7. PUT /resource nên cập nhật một đối tượng tài nguyên.
  8. PATCH /resource nên cập nhật một tài nguyên bằng cách chỉ đăng các thuộc tính đã thay đổi.
  9. PATCH /resources Nên cập nhật hàng loạt tài nguyên chỉ đăng các thuộc tính thay đổi.
  10. DELETE /resourcesnên xóa tất cả tài nguyên; đùa thôi: 400 mã trạng thái
  11. DELETE /resource/id/{resourceId}

Cách tiếp cận này là linh hoạt nhất và giàu tính năng, nhưng cũng tốn thời gian nhất để phát triển. Vì vậy, nếu bạn đang vội (luôn luôn là trường hợp phát triển phần mềm), chỉ cần đặt tên cho điểm cuối của bạn resourcehoặc dạng số nhiều resources. Tôi thích hình thức số ít vì nó cung cấp cho bạn tùy chọn để xem xét và đánh giá theo chương trình vì không phải tất cả các hình thức số nhiều đều kết thúc bằng 's'.

Đã nói tất cả, vì bất kỳ lý do gì, các nhà phát triển thực hành được sử dụng phổ biến nhất đã chọn là sử dụng hình thức số nhiều. Đây cuối cùng là con đường tôi đã chọn và nếu bạn nhìn vào apis phổ biến như githubtwitter, đây là những gì họ làm.

Một số tiêu chí để quyết định có thể là:

  1. Hạn chế thời gian của tôi là gì?
  2. Những hoạt động nào tôi sẽ cho phép người tiêu dùng của tôi làm?
  3. Yêu cầu và tải trọng kết quả trông như thế nào?
  4. Tôi có muốn sử dụng sự phản chiếu và phân tích URI trong mã của mình không?

Vì vậy, nó tùy thuộc vào bạn. Chỉ cần bất cứ điều gì bạn làm là nhất quán.


1
Có vẻ như hình thức số nhiều đã được chọn vì các nhà phát triển dường như cho rằng tất cả các tài nguyên vốn là một phần của bộ sưu tập. Tuy nhiên, "quy ước được chấp nhận" dường như chỉ ra rằng POST /usersnên tạo một người dùng duy nhất, thêm nó vào bộ sưu tập. Tôi không đồng ý. POST /usersnên tạo một danh sách người dùng (ngay cả khi đó là danh sách 1), trong đó POST /usersẽ tạo chính xác một người dùng. Tôi thấy không có lý do tại sao cả hai điểm cuối tài nguyên số nhiều và số ít không thể cùng tồn tại. Họ mô tả các hành vi khác nhau và không gây ngạc nhiên cho bất kỳ ai về chức năng của họ.
đè bẹp

Không có quy ước để chỉ định id tài nguyên trong đường dẫn phải không? Nếu vậy, nó dường như bị bỏ rơi rộng rãi. Ví dụ, POST users/<id>sẽ tạo một người dùng mới.
Tom Russell

1
@TomRussell thường là máy chủ tạo id, vì vậy bạn sẽ không biết id để POST.
Alex

3
@TomRussell, khi máy khách xác định (một loại) id khi tạo tài nguyên mới, nó sẽ được sử dụng phổ biến hơn PUT /users/<id>thay vì POST. POSTcó cách diễn giải "thêm phần này vào bộ sưu tập và xác định id là một phần của điều đó". PUTcó cách hiểu "cập nhật (hoặc thêm) tài nguyên này với id này." Xem restcookbook.com/HTTP%20Methods/put-vs-post để được giải thích dài hơn về nguyên tắc này.
Joool Schulenklopper

Tôi không tin việc so sánh với Twitters API là công bằng khi họ sử dụng biểu mẫu số nhiều cho tất cả các điểm cuối của họ. Họ không trộn lẫn số nhiều và số ít cho cùng một yếu tố.
Andrew T Finnell

7

Hai xu của tôi: các phương pháp dành thời gian thay đổi từ số nhiều sang số ít hoặc ngược lại là một sự lãng phí chu kỳ CPU. Tôi có thể là trường học cũ, nhưng trong thời gian của tôi như mọi thứ được gọi là như nhau. Làm thế nào để tôi tìm kiếm các phương pháp liên quan đến mọi người? Không có biểu hiện thường xuyên sẽ bao gồm cả người và người mà không có tác dụng phụ không mong muốn.

Số nhiều tiếng Anh có thể rất độc đoán và họ mã hóa mã không cần thiết. Bám sát một quy ước đặt tên. Ngôn ngữ máy tính được cho là về sự rõ ràng toán học, không phải là bắt chước ngôn ngữ tự nhiên.


2
Mã địa chỉ này cố gắng "tự động tạo / mangle" điểm cuối (có nhiều thư viện có ý kiến ​​giả định số nhiều / số ít và cố gắng ánh xạ); tuy nhiên, điều này không áp dụng cho các tên điểm cuối được chọn rõ ràng hơn là chọn từ đúng (bất kể nó được chia số nhiều như thế nào).
dùng2864740

6

Tôi thích sử dụng hình thức số ít cho cả sự đơn giản và nhất quán.

Ví dụ: xem xét các url sau:

/ khách hàng / 1

Tôi sẽ coi khách hàng là bộ sưu tập của khách hàng, nhưng để đơn giản, phần bộ sưu tập bị loại bỏ.

Một vi dụ khac:

/ thiết bị / 1

Trong trường hợp này, thiết bị không phải là hình thức số nhiều chính xác. Vì vậy, coi nó như một bộ sưu tập thiết bị và loại bỏ bộ sưu tập cho đơn giản làm cho nó phù hợp với trường hợp khách hàng.


2
POST / khách hàng có vẻ như sẽ thay thế một và chỉ một khách hàng. Đây là nỗi đau lớn nhất của tôi với việc sử dụng tên tài nguyên số ít.
Andrew T Finnell

2
@ andrew-t-finnell Không POST /customerđược phép làm điều đó - chèn một khách hàng?
donmutti

Nó chèn một Khách hàng vào bộ sưu tập Khách hàng. POST /customerđọc cho tôi như thể nó đang gửi cho thekhách hàng. Không phải là một bộ sưu tập của khách hàng. Tuy nhiên, tôi sẽ thừa nhận rằng số nhiều hoặc không số nhiều là một ưu tiên. Miễn là chúng không bị trộn lẫn như câu trả lời khác. Điều đó sẽ vô cùng khó hiểu.
Andrew T Finnell

"BÀI ĐĂNG cho khách hàng" không có ý nghĩa gì trong trường hợp này. POST không thay thế, nó chèn. Có lẽ nếu đó là POST / khách hàng / 1 tôi có thể thấy tình huống khó xử, nhưng ngay cả điều đó cũng không có ý nghĩa gì từ góc độ REST, bởi vì bạn đang chèn cái gì? Nó sẽ là / khách hàng / 1 / hóa đơn hoặc / khách hàng / 1 / biên lai, v.v.
chết tiệt

5

Một id trong một tuyến đường nên được xem giống như một chỉ mục cho một danh sách và việc đặt tên sẽ được tiến hành tương ứng.

numbers = [1, 2, 3]

numbers            GET /numbers
numbers[1]         GET /numbers/1
numbers.push(4)    POST /numbers
numbers[1] = 23    UPDATE /numbers/1

Nhưng một số tài nguyên không sử dụng id trong các tuyến đường của họ vì chỉ có một hoặc một người dùng không bao giờ có quyền truy cập vào nhiều hơn một, vì vậy những danh sách đó không có trong danh sách:

GET /dashboard
DELETE /session
POST /login
GET /users/{:id}/profile
UPDATE /users/{:id}/profile

4

Với các quy ước đặt tên, thường thì an toàn khi nói "chỉ cần chọn một và tuân theo nó", điều này có ý nghĩa.

Tuy nhiên, sau khi phải giải thích REST cho nhiều người, đại diện cho các điểm cuối là đường dẫn trên hệ thống tệp là cách thực hiện rõ ràng nhất.
Nó không trạng thái (các tệp tồn tại hoặc không tồn tại), phân cấp, đơn giản và quen thuộc - bạn đã biết cách truy cập các tệp tĩnh, cho dù cục bộ hoặc qua http.

Và trong bối cảnh đó, các quy tắc ngôn ngữ chỉ có thể giúp bạn đi xa như sau:

Một thư mục có thể chứa nhiều tệp và / hoặc thư mục con, và do đó tên của nó phải ở dạng số nhiều.

Và tôi thích điều đó.
Mặc dù, mặt khác - đó là thư mục của bạn, bạn có thể đặt tên cho nó là "a-resource-or-multi-resource" nếu đó là những gì bạn muốn. Đó không thực sự là điều quan trọng.

Điều quan trọng là nếu bạn đặt một tệp có tên "123" trong thư mục có tên "resourceS" (kết quả là /resourceS/123), thì bạn không thể mong đợi nó có thể truy cập được thông qua /resource/123.

Đừng cố làm cho nó thông minh hơn nó phải - thay đổi từ số nhiều sang số ít tùy thuộc vào số lượng tài nguyên bạn đang truy cập có thể làm hài lòng một số người, nhưng nó không hiệu quả và nó không có ý nghĩa hệ thống phân cấp .

Lưu ý: Về mặt kỹ thuật, bạn có thể tạo "liên kết tượng trưng", do đó /resources/123cũng có thể được truy cập qua /resource/123, nhưng trước đây vẫn phải tồn tại!


3

Hãy xem Hướng dẫn thiết kế API của Google : Tên tài nguyên để thực hiện việc đặt tên tài nguyên khác.

Nói ngắn gọn:

  • Bộ sưu tập được đặt tên với số nhiều.
  • Tài nguyên cá nhân được đặt tên bằng một chuỗi.
|--------------------------+---------------+-------------------+---------------+--------------|
| API Service Name         | Collection ID | Resource ID       | Collection ID | Resource ID  |
|--------------------------+---------------+-------------------+---------------+--------------|
| //mail.googleapis.com    | /users        | /name@example.com | /settings     | /customFrom  |
| //storage.googleapis.com | /buckets      | /bucket-id        | /objects      | /object-id   |
|--------------------------+---------------+-------------------+---------------+--------------|

Thật đáng để đọc nếu bạn đang nghĩ về chủ đề này.


2

Sử dụng số nhiều cho tất cả các phương thức là thực tế hơn ít nhất ở một khía cạnh: nếu bạn đang phát triển và thử nghiệm API tài nguyên bằng Postman (hoặc công cụ tương tự), bạn không cần chỉnh sửa URI khi chuyển từ GET sang PUT sang POST, v.v. .


1
Đó không phải là một đối số đối với tôi vì Postman cung cấp các bộ sưu tập, vì vậy bạn có thể lưu tất cả các tài nguyên dưới dạng các mục bộ sưu tập khác nhau và kiểm tra chúng riêng lẻ. Tất cả những gì bạn làm là chọn tài nguyên từ bộ sưu tập, bạn không phải chỉnh sửa tham số / phương thức / vv mọi lúc.
Wirone

1

Cả hai đại diện đều hữu ích. Tôi đã sử dụng số ít để thuận tiện trong một thời gian khá lâu, tình trạng viêm có thể khó khăn. Kinh nghiệm của tôi trong việc phát triển các API REST đơn lẻ nghiêm ngặt, các nhà phát triển sử dụng điểm cuối thiếu sự chắc chắn về hình dạng của kết quả có thể là gì. Bây giờ tôi thích sử dụng thuật ngữ mô tả đúng nhất hình dạng của phản hồi.

Nếu tất cả các tài nguyên của bạn ở cấp cao nhất, thì bạn có thể thoát khỏi các biểu diễn số ít. Tránh viêm là một chiến thắng lớn.

Nếu bạn đang thực hiện bất kỳ loại liên kết sâu nào để thể hiện các truy vấn về mối quan hệ, thì các nhà phát triển viết chống lại API của bạn có thể được hỗ trợ bằng cách có một quy ước chặt chẽ hơn.

Quy ước của tôi là mỗi cấp độ sâu trong URI đang mô tả sự tương tác với tài nguyên gốc và URI đầy đủ sẽ mô tả ngầm định những gì đang được truy xuất.

Giả sử chúng ta có mô hình sau.

interface User {
    <string>id;
    <Friend[]>friends;
    <Manager>user;
}

interface Friend {
    <string>id;
    <User>user;
    ...<<friendship specific props>>
}

Nếu tôi cần cung cấp một tài nguyên cho phép khách hàng có được người quản lý của một người bạn cụ thể của một người dùng cụ thể, thì nó có thể trông giống như:

GET /users/{id}/friends/{friendId}/manager

Sau đây là một số ví dụ khác:

  • GET /users - liệt kê tài nguyên người dùng trong bộ sưu tập người dùng toàn cầu
  • POST /users - tạo người dùng mới trong bộ sưu tập người dùng toàn cầu
  • GET /users/{id} - lấy một người dùng cụ thể từ bộ sưu tập người dùng toàn cầu
  • GET /users/{id}/manager - có được người quản lý của một người dùng cụ thể
  • GET /users/{id}/friends - có được danh sách bạn bè của người dùng
  • GET /users/{id}/friends/{friendId} - có được một người bạn cụ thể của người dùng
  • LINK /users/{id}/friends - thêm một hiệp hội bạn bè cho người dùng này
  • UNLINK /users/{id}/friends - xóa liên kết bạn bè khỏi người dùng này

Lưu ý cách mỗi cấp độ ánh xạ tới cha mẹ có thể được hành động. Sử dụng cha mẹ khác nhau cho cùng một đối tượng là phản trực giác. Lấy một tài nguyên tại các GET /resource/123lá mà không có dấu hiệu cho thấy việc tạo một tài nguyên mới nên được thực hiện tạiPOST /resources


1

Tôi biết hầu hết mọi người đang ở giữa quyết định nên sử dụng số nhiều hay số ít. Vấn đề chưa được giải quyết ở đây là khách hàng sẽ cần biết bạn đang sử dụng cái nào và họ luôn có khả năng mắc lỗi. Đây là nơi đề nghị của tôi đến từ.

Làm thế nào về cả hai? Và bằng cách đó, tôi có nghĩa là sử dụng số ít cho toàn bộ API của bạn và sau đó tạo các tuyến để chuyển tiếp các yêu cầu được thực hiện ở dạng số nhiều sang dạng số ít. Ví dụ:

GET  /resources     =     GET  /resource
GET  /resources/1   =     GET  /resource/1
POST /resources/1   =     POST /resource/1
...

Bạn nhận được hình ảnh. Không ai sai, nỗ lực tối thiểu và khách hàng sẽ luôn luôn làm đúng.


1
Nếu bạn đang thực hiện chuyển hướng 302 và bộ nhớ cache của bạn đang lưu trữ mọi thứ hai lần, bạn đã thiết lập sai bộ đệm của mình. Bộ nhớ cache không có nghĩa là lưu trữ 302 chuyển hướng.
wynnset

2
Nếu khách hàng của bạn luôn sử dụng /resourcesvà luôn được chuyển hướng đến /resource, bạn đã làm sai. Nếu người khác sử dụng API của bạn, họ có thể sử dụng URL chính xác trực tiếp hoặc được chuyển hướng (hoạt động nhưng sai) và chính bạn là người đã mở sai cách.
maaartinus

Không chắc chắn bởi những gì bạn có nghĩa là "sai" - đó là rất chủ quan. Nó không thực sự sai bởi vì nó hoạt động.
wynnset

Điều này làm tăng chi phí bảo trì và chi phí hiểu biết và số lượng mã cần thiết.
Will Sheppard

1

Tôi không muốn thấy {id}một phần của các URL trùng lặp với các tài nguyên phụ, vì idvề mặt lý thuyết có thể là bất cứ điều gì và sẽ có sự mơ hồ. Nó đang trộn các khái niệm khác nhau (định danh và tên tài nguyên phụ).

Vấn đề tương tự thường thấy trong enumcác hằng số cấu trúc thư mục hoặc các khái niệm khác nhau là hỗn hợp (ví dụ, khi bạn có thư mục Tigers, LionsCheetahs, và sau đó còn là một thư mục có tên Animalscùng cấp - điều này làm cho không có ý nghĩa là một là một tập hợp con của khác).

Nói chung, tôi nghĩ rằng phần được đặt tên cuối cùng của một điểm cuối nên là số ít nếu nó liên quan đến một thực thể duy nhất tại một thời điểm và số nhiều nếu nó liên quan đến một danh sách các thực thể.

Vì vậy, các điểm cuối liên quan đến một người dùng:

GET  /user             -> Not allowed, 400
GET  /user/{id}        -> Returns user with given id
POST /user             -> Creates a new user
PUT  /user/{id}        -> Updates user with given id
DELETE /user/{id}      -> Deletes user with given id

Sau đó, có tài nguyên riêng để thực hiện truy vấn trên người dùng, thường trả về một danh sách:

GET /users             -> Lists all users, optionally filtered by way of parameters
GET /users/new?since=x -> Gets all users that are new since a specific time
GET /users/top?max=x   -> Gets top X active users

Và đây là một số ví dụ về tài nguyên phụ liên quan đến một người dùng cụ thể:

GET /user/{id}/friends -> Returns a list of friends of given user

Kết bạn (liên kết nhiều đến nhiều):

PUT /user/{id}/friend/{id}     -> Befriends two users
DELETE /user/{id}/friend/{id}  -> Unfriends two users
GET /user/{id}/friend/{id}     -> Gets status of friendship between two users

Không bao giờ có bất kỳ sự mơ hồ nào, và việc đặt tên số nhiều hoặc số ít của tài nguyên là một gợi ý cho người dùng những gì họ có thể mong đợi (danh sách hoặc đối tượng). Không có hạn chế nào đối với ids, về mặt lý thuyết cho phép người dùng có id newmà không bị trùng lặp với tên tài nguyên phụ (tương lai tiềm năng).


1

Sử dụng Singular và tận dụng quy ước tiếng Anh được thấy trong ví dụ "Danh bạ doanh nghiệp".

Rất nhiều thứ được đọc theo cách này: "Vỏ sách", "Gói chó", "Phòng trưng bày nghệ thuật", "Liên hoan phim", "Lô xe", v.v.

Điều này thuận tiện phù hợp với đường dẫn url từ trái sang phải. Loại vật phẩm bên trái. Đặt loại bên phải.

GET /usersthực sự bao giờ lấy một tập hợp người dùng? Không thường xuyên. Nó tìm nạp một bộ sơ khai chứa khóa và có thể là tên người dùng. Vì vậy, nó không thực sự /usersdù sao. Đó là một chỉ mục của người dùng hoặc "chỉ mục người dùng" nếu bạn muốn. Tại sao không gọi nó là? Đó là một /user/index. Vì chúng tôi đã đặt tên cho loại thiết lập, chúng tôi có thể có nhiều loại hiển thị các hình chiếu khác nhau của người dùng mà không cần dùng đến các tham số truy vấn, ví dụ như user/phone-listhoặc/user/mailing-list .

Còn người dùng 300 thì sao? Nó vẫn vậy /user/300.

GET /user/index
GET /user/{id}

POST /user
PUT /user/{id}

DELETE /user/{id}

Khi kết thúc, HTTP chỉ có thể có một phản hồi cho một yêu cầu duy nhất. Một con đường luôn luôn đề cập đến một số ít.


-1

Đối với tôi, số nhiều thao túng bộ sưu tập , trong khi số ít thao túng vật phẩm trong bộ sưu tập đó.

Bộ sưu tập cho phép các phương thức GET / POST / DELETE

Mục cho phép các phương thức GET / PUT / DELETE

Ví dụ

POST trên / sinh viên sẽ thêm một sinh viên mới trong trường.

XÓA trên / học sinh sẽ loại bỏ tất cả các học sinh trong trường.

XÓA vào / sinh viên / 123 sẽ loại bỏ sinh viên 123 khỏi trường.

Nó có thể cảm thấy như không quan trọng nhưng một số kỹ sư đôi khi quên id. Nếu tuyến đường luôn ở dạng số nhiều và thực hiện XÓA, bạn có thể vô tình xóa sạch dữ liệu của mình. Trong khi thiếu id trên số ít sẽ trả về một lộ trình 404 không tìm thấy.

Để tiếp tục mở rộng ví dụ nếu API được cho là phơi bày nhiều trường, thì đại loại như

XÓA trên / trường / abc / học sinh sẽ loại bỏ tất cả các học sinh trong trường abc.

Chọn từ đúng đôi khi là một thách thức của riêng nó, nhưng tôi thích duy trì số nhiều cho bộ sưu tập. Ví dụ cart_itemshoặc cart/itemscảm thấy đúng. Ngược lại xóa cart, xóa đối tượng giỏ hàng tự nó và không phải các mục trong giỏ hàng;).


Không nên chia cái này là / giỏ hàng và / giỏ hàng / vật phẩm chứ? Sau đó, bạn có thể giải quyết toàn bộ giỏ hàng (ví dụ như xóa) hoặc các mục riêng lẻ?
Rob Grant

@RobertGrant Sẽ không phải là "/ xe đẩy / vật phẩm / 123"? (ví dụ: tại sao "giỏ hàng" chứ không phải "xe đẩy" là quy tắc 'luôn luôn số nhiều'?)
user2864740

1
Tôi tranh luận rằng nếu mã sản xuất được kiểm tra có thể thực hiện xóa các mục trong giỏ hàng của mọi người thì có vấn đề lớn hơn quy ước đặt tên. Khả năng họ sẽ nhớ 's' trên ID ít hơn nhiều.
Andrew T Finnell

bất cứ ai cũng có thể tạo một điểm cuối chỉ đơn giản là xóa toàn bộ bộ sưu tập? Có vẻ cực kỳ nguy hiểm đối với tôi và có lẽ cũng là lý do tại sao REST không thực sự hỗ trợ xóa hàng loạt. (bạn sẽ phải bọc mảng thành một đối tượng). Nếu tôi thực sự cần một điểm cuối để xóa toàn bộ bộ sưu tập, tôi sẽ đảm bảo rằng URI rất độc đáo và chắc chắn không giống với POST
cnps

-1

Làm thế nào về:

/resource/(không /resource)

/resource/ có nghĩa là thư mục chứa thứ gọi là "tài nguyên", đó là thư mục "resouce".

Và tôi cũng nghĩ rằng quy ước đặt tên của các bảng cơ sở dữ liệu là giống nhau, ví dụ, một bảng có tên 'user' là "bảng người dùng", nó chứa một thứ gọi là "user".


-2

Tôi thích sử dụng cả số nhiều ( /resources) và số ít (/resource/{id} ) vì tôi nghĩ rằng nó phân tách rõ ràng hơn logic giữa làm việc trên bộ sưu tập tài nguyên và làm việc trên một tài nguyên.

Là một tác dụng phụ quan trọng của việc này, nó cũng có thể giúp ngăn người khác sử dụng API sai. Ví dụ: hãy xem xét trường hợp người dùng cố gắng lấy tài nguyên sai bằng cách chỉ định Id là một tham số như thế này:

GET /resources?Id=123

Trong trường hợp này, khi chúng tôi sử dụng phiên bản số nhiều, máy chủ rất có thể sẽ bỏ qua tham số Id và trả về danh sách tất cả các tài nguyên. Nếu người dùng không cẩn thận, anh ta sẽ nghĩ rằng cuộc gọi đã thành công và sử dụng tài nguyên đầu tiên trong danh sách.

Mặt khác, khi sử dụng dạng số ít:

GET /resource?Id=123

máy chủ rất có thể sẽ trả về lỗi vì Id không được chỉ định đúng cách và người dùng sẽ phải nhận ra rằng có gì đó không đúng.


1
Tại sao bạn trộn thành ngữ ở đây? Bạn sử dụng ký hiệu URI thích hợp trong đoạn đầu tiên và sau đó chuyển sang tham số truy vấn? Sử dụng các tham số truy vấn để có được tài nguyên có ID là 123 hoàn toàn không có cơ sở ở đây.
Andrew T Finnell

Đó rõ ràng là một sai lầm. Tôi đã cập nhật câu trả lời của tôi bây giờ. Cảm ơn đã chú ý đến nó.
pberggreen

Sau khi bị đánh giá thấp một lần nữa, tôi nhìn vào những gì tôi đã viết và tôi nhận ra rằng bài viết gốc là chính xác. Quan điểm của tôi là chính xác rằng nếu người dùng làm sai, thì thực tế sử dụng số nhiều + số ít sẽ đưa ra một thông báo lỗi tốt hơn chỉ sử dụng số nhiều.
pberggreen

Tôi vẫn cảm thấy điều này là khó hiểu vấn đề trong tay. Ý tưởng sử dụng số nhiều là một bộ sưu tập. Và con số ở cuối là một chỉ số vào bộ sưu tập. Điều gì nếu bạn NHẬN / tài nguyên của chính nó? Sử dụng cả số nhiều và số ít với nhau là khá khó hiểu. Nói / tài nguyên / 123 nói: Nhận tài nguyên 123 của tôi trong nhóm tài nguyên.
Andrew T Finnell
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.