Thiết kế api REST bằng URI so với chuỗi truy vấn


73

Hãy nói rằng tôi có ba tài nguyên có liên quan như vậy:

Grandparent (collection) -> Parent (collection) -> and Child (collection)

Trên đây mô tả mối quan hệ giữa các tài nguyên này như sau: Mỗi ông bà có thể ánh xạ tới một hoặc một số cha mẹ. Mỗi phụ huynh có thể ánh xạ tới một hoặc một vài đứa trẻ. Tôi muốn khả năng hỗ trợ tìm kiếm dựa vào tài nguyên con nhưng với tiêu chí bộ lọc:

Nếu khách hàng của tôi chuyển cho tôi một tài liệu tham khảo id cho ông bà, tôi muốn chỉ tìm kiếm những đứa trẻ là con cháu trực tiếp của ông bà đó.

Nếu khách hàng của tôi chuyển cho tôi một tài liệu tham khảo id cho cha mẹ, tôi muốn chỉ tìm kiếm những đứa trẻ là con cháu trực tiếp của cha mẹ tôi.

Tôi đã nghĩ về một cái gì đó như vậy:

GET /myservice/api/v1/grandparents/{grandparentID}/parents/children?search={text}

GET /myservice/api/v1/parents/{parentID}/children?search={text}

cho các yêu cầu trên, tương ứng.

Nhưng tôi cũng có thể làm một cái gì đó như thế này:

GET /myservice/api/v1/children?search={text}&grandparentID={id}&parentID=${id}

Trong thiết kế này, tôi có thể cho phép khách hàng của mình chuyển cho tôi cái này hoặc cái kia trong chuỗi truy vấn: grandparentID hoặc ParentID, nhưng không phải cả hai.

Câu hỏi của tôi là:

1) Thiết kế API nào RESTful hơn và tại sao? Về mặt ngữ nghĩa, chúng có nghĩa và hành xử theo cùng một cách. Tài nguyên cuối cùng trong URI là "trẻ em", ngụ ý hiệu quả rằng máy khách đang hoạt động trên tài nguyên trẻ em.

2) Những ưu và nhược điểm của mỗi khía cạnh về mức độ dễ hiểu theo quan điểm của khách hàng và khả năng duy trì từ quan điểm của nhà thiết kế.

3) Chuỗi truy vấn thực sự được sử dụng để làm gì, ngoài "lọc" trên tài nguyên của bạn? Nếu bạn đi theo cách tiếp cận đầu tiên, tham số bộ lọc được nhúng vào chính URI dưới dạng tham số đường dẫn thay vì tham số chuỗi truy vấn.

Cảm ơn!


3
Tiêu đề của câu hỏi của bạn sẽ vô cùng khó hiểu với bất cứ ai xem nó. Các phân đoạn hợp lệ của một URI được xác định là <em> mật khẩu> không được dùng nữa) "Chuỗi truy vấn" là thành phần hợp lệ của URI, do đó "vs" trong tiêu đề của bạn là một cuộc nói chuyện điên rồ.
K. Alan Bates

Ý bạn là I want to only search against children who are INdirect descendants of that grandparent.sao Theo cấu trúc của bạn, Grandparent không có con trực tiếp.
null

Sự khác biệt giữa một đứa trẻ và cha mẹ là gì? Cha mẹ có phải là cha mẹ nếu anh ta không có con? Mùi của lỗi thiết kế
Pinoniq

re: potential design flawvà nếu bạn có thông tin về một người nhưng không có thông tin về cha mẹ của họ, họ có đủ điều kiện là một child? (ví dụ: Adam và Eva) :)
Jesse Chisholm

Câu trả lời:


64

Đầu tiên

Theo RFC 3986 §3.4 (Số nhận dạng tài nguyên đồng nhất § (Thành phần cú pháp) | Truy vấn

3,4 Truy vấn

Thành phần truy vấn chứa dữ liệu không phân cấp, cùng với dữ liệu trong thành phần đường dẫn (Mục 3.3), phục vụ để xác định tài nguyên trong phạm vi của lược đồ và quyền đặt tên của URI (nếu có).

Các thành phần truy vấn là để lấy dữ liệu không phân cấp; Có một vài thứ trong tự nhiên hơn là một cây gia đình! Ergo - bất kể bạn nghĩ đó là "REST-y" hay không - để tuân thủ các định dạng, giao thức và khung của và để phát triển hệ thống trên internet, bạn không được sử dụng chuỗi truy vấn để xác định thông tin này.

REST không có gì để làm với định nghĩa này.

Trước khi giải quyết các câu hỏi cụ thể của bạn, tham số truy vấn "tìm kiếm" của bạn được đặt tên kém. Tốt hơn là coi phân đoạn truy vấn của bạn là một từ điển của các cặp khóa-giá trị.

Chuỗi truy vấn của bạn có thể được định nghĩa phù hợp hơn là

?first_name={firstName}&last_name={lastName}&birth_date={birthDate} Vân vân.

Để trả lời các câu hỏi cụ thể của bạn

1) Thiết kế API nào RESTful hơn và tại sao? Về mặt ngữ nghĩa, chúng có nghĩa và hành xử theo cùng một cách. Tài nguyên cuối cùng trong URI là "trẻ em", ngụ ý hiệu quả rằng máy khách đang hoạt động trên tài nguyên trẻ em.

Tôi không nghĩ rằng điều này rõ ràng như bạn tin tưởng.

Không có giao diện tài nguyên nào trong số này là RESTful. Điều kiện tiên quyết chính cho phong cách kiến ​​trúc RESTful là các chuyển đổi Trạng thái ứng dụng phải được truyền thông từ máy chủ dưới dạng hypermedia. Mọi người đã làm việc với cấu trúc của các URI để biến chúng thành "URI RESTful" bằng cách nào đó nhưng tài liệu chính thức về REST thực sự có rất ít điều để nói về điều này. Ý kiến ​​cá nhân của tôi là phần lớn thông tin sai lệch về REST đã được xuất bản với mục đích phá bỏ những thói quen xấu, cũ. .

Điều mà tài liệu REST nói là nếu bạn định sử dụng HTTP làm giao thức ứng dụng của mình, bạn phải tuân thủ các yêu cầu chính thức về thông số kỹ thuật của giao thức và bạn không thể "tạo ra http khi bạn đi và vẫn tuyên bố rằng bạn đang sử dụng http" ; nếu bạn định sử dụng URI để xác định tài nguyên của mình, bạn phải tuân thủ các yêu cầu chính thức của thông số kỹ thuật về URI / URL.

Câu hỏi của bạn được giải quyết trực tiếp bởi RFC3986 §3.4, mà tôi đã liên kết ở trên. Điểm mấu chốt của vấn đề này là mặc dù URI tuân thủ không đủ để xem xét API "RESTful", nếu bạn muốn hệ thống của mình thực sự "RESTful" và bạn đang sử dụng HTTP và URI, thì bạn không thể xác định dữ liệu phân cấp thông qua chuỗi truy vấn vì:

3,4 Truy vấn

Thành phần truy vấn chứa dữ liệu không phân cấp

...Nó đơn giản như vậy.

2) Những ưu và nhược điểm của mỗi khía cạnh về mức độ dễ hiểu theo quan điểm của khách hàng và khả năng duy trì từ quan điểm của nhà thiết kế.

"Ưu điểm" của hai người đầu tiên là họ đang đi đúng hướng . "Nhược điểm" của cái thứ ba là nó dường như bị sai.

Theo như sự hiểu biết và khả năng bảo trì của bạn, những điều đó chắc chắn là chủ quan và phụ thuộc vào mức độ hiểu của nhà phát triển khách hàng và các nhóm thiết kế của nhà thiết kế. Đặc tả URI là câu trả lời dứt khoát về cách các URI được định dạng. Dữ liệu phân cấp được cho là được thể hiện trên đường dẫn và với các tham số đường dẫn. Dữ liệu không phân cấp được cho là được thể hiện trong truy vấn. Đoạn này phức tạp hơn, bởi vì ngữ nghĩa của nó phụ thuộc cụ thể vào loại phương tiện truyền thông của đại diện được yêu cầu. Vì vậy, để giải quyết thành phần "dễ hiểu" trong câu hỏi của bạn, tôi sẽ cố gắng dịch chính xác hai URI đầu tiên của bạn đang thực sự nói gì. Sau đó, tôi sẽ cố gắng thể hiện những gì bạn nói bạn đang cố gắng thực hiện với các URI hợp lệ.

Dịch các URI nguyên văn của bạn sang nghĩa ngữ nghĩa của chúng /myservice/api/v1/grandparents/{grandparentID}/parents/children?search={text} Điều này nói với cha mẹ của ông bà, tìm con của họ có search={text} những gì bạn nói với URI của bạn chỉ mạch lạc nếu tìm kiếm anh chị em của ông bà. Với "ông bà, cha mẹ, con cái", bạn đã tìm thấy một "ông bà" đã đi lên một thế hệ với cha mẹ của họ và sau đó quay trở lại thế hệ "ông bà" bằng cách nhìn vào con cái của cha mẹ.

/myservice/api/v1/parents/{parentID}/children?search={text} Điều này nói rằng đối với cha mẹ được xác định bởi {ParentID}, hãy tìm con của họ Có điều ?search={text}này gần đúng hơn với những gì bạn muốn và thể hiện mối quan hệ cha mẹ-> con có thể được sử dụng để mô hình hóa toàn bộ API của bạn. Để mô hình hóa nó theo cách này, gánh nặng được đặt lên khách hàng để nhận ra rằng nếu họ có "ông bà", thì có một lớp không xác định giữa ID họ có và phần biểu đồ gia đình họ muốn xem. Để tìm "đứa con" của "grandparentId", bạn có thể gọi /parents/{parentID}/childrendịch vụ của mình và sau đó thông báo cho đứa trẻ được trả lại, tìm kiếm con của chúng để nhận dạng người của bạn.

Việc thực hiện các yêu cầu của bạn dưới dạng URI Nếu bạn muốn mô hình hóa một mã định danh tài nguyên có thể mở rộng hơn có thể đi trên cây, tôi có thể nghĩ ra một số cách bạn có thể thực hiện được.

1) Cái đầu tiên, tôi đã ám chỉ. Biểu diễn biểu đồ "Con người" dưới dạng cấu trúc tổng hợp. Mỗi người có một tham chiếu đến thế hệ bên trên nó thông qua con đường Cha mẹ của nó và đến một thế hệ bên dưới nó thông qua con đường Con cái của nó.

/Persons/Joe/Parents/Mother/Parents sẽ là một cách để lấy ông bà ngoại của Joe.

/Persons/Joe/Parents/Parents sẽ là một cách để lấy tất cả ông bà của Joe.

/Persons/Joe/Parents/Parents?id={Joe.GrandparentID} sẽ lấy ông bà của Joe có số nhận dạng bạn có trong tay.

và tất cả đều có ý nghĩa (lưu ý rằng có thể có hình phạt hiệu suất ở đây tùy theo nhiệm vụ bằng cách buộc một dfs trên máy chủ do thiếu nhận dạng chi nhánh trong mẫu "Cha mẹ / Cha mẹ / Cha mẹ".) Bạn cũng được hưởng lợi từ việc có khả năng hỗ trợ bất kỳ số lượng thế hệ tùy ý. Nếu, vì một số lý do, bạn mong muốn tìm kiếm 8 thế hệ, bạn có thể đại diện cho điều này như

/Persons/Joe/Parents/Parents/Parents/Parents/Parents/Parents/Parents/Parents?id={Joe.NotableAncestor}

nhưng điều này dẫn đến tùy chọn chi phối thứ hai để thể hiện dữ liệu này: thông qua một tham số đường dẫn.


2) Sử dụng tham số đường dẫn để "truy vấn phân cấp" Bạn có thể phát triển cấu trúc sau để giúp giảm bớt gánh nặng cho người tiêu dùng và vẫn có API có ý nghĩa.

Để nhìn lại 147 thế hệ, việc biểu thị định danh tài nguyên này bằng các tham số đường dẫn cho phép bạn thực hiện

/Persons/Joe/Parents;generations=147?id={Joe.NotableAncestor}

Để xác định vị trí của Joe từ Ông cố của anh ấy, bạn có thể nhìn xuống biểu đồ một số thế hệ đã biết cho Id của Joe. /Persons/JoesGreatGrandparent/Children;generations=3?id={Joe.Id}

Điều quan trọng cần lưu ý với các cách tiếp cận này là không có thêm thông tin trong mã định danh và yêu cầu, bạn nên mong đợi rằng URI đầu tiên đang truy xuất một thế hệ 147 người từ Joe với mã định danh Joe.NotableAncestor. Bạn nên mong đợi người thứ hai lấy Joe. Giả sử rằng những gì bạn thực sự muốn là cho máy khách gọi của bạn có thể truy xuất toàn bộ tập hợp các nút và mối quan hệ của chúng giữa Người gốc và bối cảnh cuối cùng của URI của bạn. Bạn có thể làm điều đó với cùng một URI (với một số trang trí bổ sung) và đặt Chấp nhận text/vnd.graphviztheo yêu cầu của bạn, đó là loại phương tiện đã đăng ký IANA cho .dotbiểu diễn đồ thị. Cùng với đó, thay đổi URI thành

/Persons/Joe/Parents;generations=147?id={Joe.NotableAncestor.Id}#directed

với Tiêu đề yêu cầu HTTP Accept: text/vnd.graphviz và bạn có thể có khách hàng giao tiếp khá rõ ràng rằng họ muốn biểu đồ được định hướng của hệ thống phân cấp thế hệ giữa Joe và 147 thế hệ trước trong đó thế hệ tổ tiên thứ 147 chứa một người được xác định là "Tổ tiên đáng chú ý" của Joe.

Tôi không chắc chắn nếu text / vnd.graphviz có bất kỳ ngữ nghĩa được xác định trước cho đoạn của nó hay không, tôi không thể tìm thấy gì trong tìm kiếm hướng dẫn. Nếu loại phương tiện đó thực sự có thông tin phân đoạn được xác định trước, thì ngữ nghĩa của nó phải được tuân theo để tạo URI phù hợp. Nhưng, nếu các ngữ nghĩa đó không được xác định trước, đặc tả URI nói rằng ngữ nghĩa của mã định danh phân đoạn không bị ràng buộc và thay vào đó được xác định bởi máy chủ, làm cho việc sử dụng này hợp lệ.


3) Chuỗi truy vấn thực sự được sử dụng để làm gì, ngoài "lọc" trên tài nguyên của bạn? Nếu bạn đi theo cách tiếp cận đầu tiên, tham số bộ lọc được nhúng vào chính URI dưới dạng tham số đường dẫn thay vì tham số chuỗi truy vấn.

Tôi tin rằng tôi đã hoàn toàn đánh bại điều này đến chết, nhưng các chuỗi truy vấn không dành cho tài nguyên "lọc". Chúng là để xác định tài nguyên của bạn từ dữ liệu không phân cấp. Nếu bạn đã đi sâu vào hệ thống phân cấp của mình bằng con đường của mình bằng cách đi /person/{id}/children/và bạn muốn xác định một đứa trẻ cụ thể hoặc một nhóm trẻ cụ thể , bạn sẽ sử dụng một số thuộc tính áp dụng cho tập hợp bạn đang xác định và đưa nó vào trong truy vấn.


1
RFC chỉ liên quan đến phân cấp trong chừng mực vì nó xác định cú pháp và thuật toán để giải quyết các tham chiếu URI tương đối. Bạn có thể giải thích hoặc trích dẫn một số nguồn giải thích tại sao các ví dụ trong bài viết gốc không phù hợp?
dùng2313838

2
Không phải là một cây gia đình thực sự là một biểu đồ không phải là một cây, và không phải là thứ bậc. xem xét nhiều cha mẹ, ly dị và tái hôn v.v.
Myster 18/2/2016

1
@RobertoAloi Đối với tôi, giao tiếp "Không tìm thấy vật phẩm" của bạn thông qua một tập hợp trống khi HTTP đã có định nghĩa cho điều đó. Nguyên tắc cơ bản là bạn yêu cầu máy chủ trả lại "thứ (s)" và nếu không có "thứ" nào trả lại, máy chủ sẽ thông báo điều đó với "404 - Không tìm thấy" Điều gì trái ngược với điều đó?
K. Alan Bates

1
Tôi luôn tin 404 để chỉ ra rằng URL gốc của tài nguyên không được tìm thấy, tức là toàn bộ bộ sưu tập. Vì vậy, nếu bạn truy vấn / sách? Tác giả = Jim và không có cuốn sách nào của jim, bạn sẽ nhận được một bộ trống []. Nhưng nếu bạn truy vấn / bài viết? Tác giả = Jim nhưng tài nguyên bài viết thậm chí không tồn tại dưới dạng bộ sưu tập 404 sẽ giúp chỉ ra rằng không có ích gì trong việc tìm kiếm bất kỳ bài viết nào cả.
chỉnh

1
@adjenks Bạn đã không học được điều đó từ thông số kỹ thuật chính thức. Về mặt cấu trúc, các thành phần của url có thể được coi là có chứa "root" nếu điều đó giúp bạn suy luận về các mục đích cho các bộ phận cấu thành, nhưng cuối cùng, chuỗi truy vấn không phải là bộ lọc hiển thị đối với tài nguyên được xác định qua đường dẫn. Chuỗi truy vấn là một công dân hạng nhất của một url. Khi bạn tìm thấy không có tài nguyên nào trên máy chủ khớp với url của bạn (bao gồm cả chuỗi truy vấn) 404 là phương tiện được xác định trong http để truyền đạt điều này. Mô hình tương tác bạn đặt ra giới thiệu một sự khác biệt mà không có sự khác biệt.
K. Alan Bates

14

Đây là nơi bạn hiểu sai:

Nếu khách hàng của tôi vượt qua tôi một tài liệu tham khảo id

Trong một hệ thống REST, máy khách không bao giờ bị làm phiền với ID. Các mã định danh tài nguyên duy nhất mà máy khách nên biết là URI. Đây là nguyên tắc của "giao diện thống nhất".

Hãy suy nghĩ về cách khách hàng sẽ tương tác với hệ thống của bạn. Giả sử người dùng bắt đầu duyệt qua danh sách ông bà, anh ta đã chọn một trong những đứa con của ông bà, đưa anh ta đến /grandparent/123. Nếu khách hàng có thể tìm kiếm trẻ em /grandparent/123, thì theo "HATEOAS", bất cứ điều gì được trả về khi bạn thực hiện truy vấn /grandparent/123sẽ trả lại URL cho giao diện tìm kiếm. URL này phải có bất kỳ dữ liệu nào cần thiết để lọc theo ông bà hiện tại được nhúng trong nó.

Cho dù liên kết trông giống /grandparent/123?search={term}hoặc /parent?grandparent=123&search={term}hoặc /parent?grandparentTerm=someterm&someothergplocator=blah&search={term}không quan trọng theo REST. Lưu ý cách tất cả các URL đó có cùng số lượng tham số, {term}mặc dù chúng sử dụng các tiêu chí khác nhau. Bạn có thể chuyển đổi giữa bất kỳ URL nào trong số đó hoặc bạn có thể kết hợp chúng tùy thuộc vào ông bà cụ thể và khách hàng sẽ không bị phá vỡ, bởi vì mối quan hệ logic giữa các tài nguyên là như nhau mặc dù việc triển khai cơ bản có thể khác nhau đáng kể.

Thay vào đó, nếu bạn đã tạo ra dịch vụ mà nó yêu cầu /grandparent/{grandparentID}?search={term}khi bạn đi một chiều nhưng /children?parent={parentID}&search={term}a} khi bạn đi một cách khác, đó là quá nhiều khớp nối vì khách hàng sẽ phải biết nội suy những điều khác nhau trên các mối quan hệ khác nhau về mặt khái niệm.

Cho dù bạn thực sự đi cùng /grandparent/123?search={term}hay /parent?grandparent=123&search={term}là một vấn đề của hương vị và bất kỳ việc thực hiện nào là dễ dàng hơn cho bạn ngay bây giờ. Điều quan trọng là không yêu cầu khách hàng phải sửa đổi nếu bạn thay đổi chiến lược URL hoặc nếu bạn sử dụng các chiến lược khác nhau trên các mối quan hệ cha mẹ và con cái khác nhau.


10

Tôi không chắc tại sao mọi người nghĩ việc đặt các giá trị ID vào URL có nghĩa là API REST, bằng cách nào đó, đó là về việc xử lý các động từ, chuyển tài nguyên.

Vì vậy, nếu bạn muốn PUT một người dùng mới, bạn phải gửi một khối dữ liệu hợp lý và yêu cầu POST http là lý tưởng, vì vậy mặc dù bạn có thể gửi khóa (ví dụ: id người dùng), bạn sẽ gửi dữ liệu người dùng (ví dụ tên, địa chỉ) dưới dạng dữ liệu POST.

Bây giờ, đó là một thành ngữ phổ biến để đặt định danh tài nguyên trong URI, nhưng đây là quy ước nhiều hơn bất kỳ hình thức chính tắc nào "không phải là REST nếu nó không nằm trong URI". Hãy nhớ rằng luận điểm ban đầu của REST hoàn toàn không đề cập đến http, đây là thành ngữ để xử lý dữ liệu trong máy chủ-máy khách, không phải là phần mở rộng cho http (mặc dù, rõ ràng, http là hình thức triển khai REST chính của chúng tôi) .

Ví dụ, Fielding sử dụng yêu cầu của một bài báo học thuật làm ví dụ. Bạn muốn lấy tài nguyên "Tài liệu của Tiến sĩ John về việc uống bia", nhưng bạn cũng có thể muốn phiên bản ban đầu hoặc phiên bản mới nhất, do đó, định danh tài nguyên có thể không phải là thứ dễ dàng được tham chiếu dưới dạng một ID duy nhất có thể được được đặt trong URI. REST cho phép điều này và một ý định đã nêu đằng sau nó là:

Thay vào đó, REST dựa vào tác giả chọn một mã định danh tài nguyên phù hợp nhất với bản chất của khái niệm được xác định

Vì vậy, không có gì ngăn bạn sử dụng URI tĩnh để truy xuất cha mẹ của bạn, chuyển một thuật ngữ tìm kiếm trong chuỗi truy vấn để xác định chính xác người dùng mà bạn theo dõi. Trong trường hợp này, 'tài nguyên' mà bạn xác định là tập hợp ông bà (và do đó, URI chứa 'ông bà' là một phần của URI. REST bao gồm khái niệm 'dữ liệu điều khiển' được thiết kế để xác định đại diện nào cho bạn tài nguyên sẽ được truy xuất - ví dụ được đưa ra trong đó là kiểm soát bộ đệm, nhưng cũng là kiểm soát phiên bản - vì vậy yêu cầu của tôi về bài báo xuất sắc của Tiến sĩ John có thể được tinh chỉnh bằng cách chuyển phiên bản dưới dạng dữ liệu điều khiển, không phải là một phần của URI.

Tôi nghĩ một ví dụ về giao diện REST thường không được đề cập là SMTP . Khi xây dựng một thông điệp thư, bạn gửi các động từ (TỪ, ĐẾN vv) với dữ liệu tài nguyên cho từng phần của thư. Đây là RESTful mặc dù nó không sử dụng các động từ http, nhưng nó sử dụng bộ riêng của nó.

Vì vậy, ... trong khi bạn cần phải có một số nhận dạng tài nguyên trong URI của mình, thì nó không phải là tài liệu tham khảo id của bạn. Điều này có thể vui vẻ được gửi dưới dạng dữ liệu điều khiển, trong chuỗi truy vấn hoặc thậm chí trong dữ liệu POST. Điều bạn thực sự xác định trong API REST là bạn đang theo đuổi một đứa trẻ mà bạn đã có trong URI của mình.

Vì vậy, theo suy nghĩ của tôi, đọc định nghĩa của REST, bạn đang yêu cầu tài nguyên con, chuyển dữ liệu điều khiển (dưới dạng chuỗi truy vấn) để xác định cái nào bạn muốn trả về. Do đó, bạn không thể thực hiện yêu cầu URI cho ông bà hoặc cha mẹ. Bạn muốn trẻ em được trả lại vì vậy thuật ngữ cha mẹ / ông bà hoặc id chắc chắn không nên có trong một URI như vậy. Trẻ em nên được.


Trên thực tế, URI như là một khái niệm là trung tâm của REST. Điều không quan trọng mặc dù là cú pháp URI. Một giao diện REST thích hợp phải xác định các tài nguyên với một cú pháp chung. Theo nguyên tắc cơ bản của REST, việc xác định tài nguyên phức tạp với một đối tượng JSON thay vì RFC 3986 URI không phải là điều xấu, mặc dù nếu bạn làm như vậy, bạn nên sử dụng JSON RI cho toàn bộ API của mình.
Nói dối Ryan

4

Rất nhiều người đã nói về ý nghĩa của REST, v.v. Nhưng dường như không ai giải quyết được vấn đề thực sự: thiết kế của bạn.

Tại sao ông bà khác cha? cả hai đều có con mà có thể có con ...

Cuối cùng, tất cả họ đều là 'con người'. Bạn có thể có điều đó trong mã của bạn là tốt. Vì vậy, sử dụng rằng:

GET /<api-endpoint>/humans/<ID>

Sẽ trả lại một số thông tin hữu ích về con người. (Tên và nội dung)

GET /<api-endpoint>/humans/<ID>/children

rõ ràng sẽ trả lại một mảng của trẻ em. Nếu không có con tồn tại, một mảng trống có lẽ là con đường để đi.

Để làm cho nó dễ dàng, ví dụ, bạn có thể thêm một cờ 'hasChildren'. hoặc 'hasGrandChildren'.

Nghĩ thông minh hơn không khó hơn


1

Dưới đây là nhiều RESTfull hơn vì mỗi ông bàID đều có URL riêng. Bằng cách này, tài nguyên được xác định theo một cách duy nhất.

GET /myservice/api/v1/grandparents/{grandparentID}
GET /myservice/api/v1/grandparents/{grandparentID}/parents/children?search={text}

Tìm kiếm tham số truy vấn là một cách tốt để thực hiện tìm kiếm từ ngữ cảnh của tài nguyên đó.

Khi một gia đình đang trở nên rất lớn, bạn có thể sử dụng bắt đầu / giới hạn làm tùy chọn truy vấn chẳng hạn:

GET /myservice/api/v1/grandparents/{grandparentID}/children?start=1&limit=50

Là nhà phát triển, thật tốt khi có các tài nguyên khác nhau với một URL / URI duy nhất. Tôi nghĩ bạn chỉ nên sử dụng tham số truy vấn khi chúng cũng có thể bị bỏ qua.

Có lẽ đây là một bài đọc tốt http: // www. Dùtworks.com / insights / blog / rest-api-design-resource-modeling và nếu không thì luận án tiến sĩ gốc của Roy T Fielding https://www.ics.uci.edu /~fielding/pub/dissertation/fielding_dissertation.pdf giải thích các khái niệm rất tốt và đầy đủ.


1

Tôi sẽ đi với

/myservice/api/v1/people/{personID}/descendants/2?search={text}

Trong trường hợp này, mọi tiền tố là một tài nguyên hợp lệ:

  • /myservice/api/v1/people: tất cả mọi người
  • /myservice/api/v1/people/{personID}: một người có thông tin đầy đủ (bao gồm tổ tiên, anh chị em, con cháu)
  • /myservice/api/v1/people/{personID}/descendants: con cháu của một người
  • /myservice/api/v1/people/{personID}/descendants/2: cháu của một người

Có thể không phải là câu trả lời tốt nhất, nhưng ít nhất có ý nghĩa với tôi.


-1

nhiều người trước đây đã chỉ ra rằng định dạng URL là không quan trọng trong bối cảnh dịch vụ RESTful ... hai xu của tôi sẽ là ... một khía cạnh quan trọng của REST như được ủng hộ trong bản gốc viết lên là khái niệm về 'Tài nguyên' .. .Khi bạn thiết kế URL của mình một khía cạnh bạn có thể cần lưu ý là 'Tài nguyên' không phải là một hàng trong một bảng duy nhất (mặc dù có thể) .. tập hợp nó là một đại diện..cũng cũng phù hợp .. .and có thể được sử dụng để thực hiện các thay đổi về trạng thái của đại diện đó (và hiệu quả là làm cơ sở lưu trữ trung bình) .. và một tài nguyên nhất định có thể chỉ có ý nghĩa trong bối cảnh kinh doanh của bạn..ví dụ;

Trong ví dụ của bạn / myservice / api / v1 / ông bà / {grandparentID} / cha mẹ / con cái? Search = {text}

Có thể là một tài nguyên có ý nghĩa hơn nếu bạn rút ngắn điều này / myservice / api / v1 / siblingsOfGrandParents? Search = ..

trong trường hợp này, bạn có thể khai báo 'siblingsOfGrandParents' là tài nguyên..đây đơn giản hóa URL

Như những người khác đã chỉ ra, có một quan niệm sai lầm phổ biến rằng bạn cần phải phù hợp với mọi loại mối quan hệ phân cấp giữa các đối tượng tên miền ở dạng rõ ràng hơn trong một URL..không có quy tắc khó và nhanh chóng để có ánh xạ 1 đến 1 giữa các đối tượng miền và tài nguyên và đại diện cho tất cả các mối quan hệ của họ ... tôi nên tin rằng câu hỏi ... có cần phải phơi bày mối quan hệ đó thông qua các URL ... cụ thể là các đoạn đường dẫn ... có lẽ không.


khi bạn dành thời gian quý báu của mình để hạ cấp một câu trả lời, sẽ rất hữu ích nếu bạn có thể lên tiếng và đưa ra lý do của mình.
Senthu Sivasambu

Tôi không hoàn toàn chắc chắn tại sao lại bị hạ thấp dựa trên việc đọc câu trả lời của bạn. Tôi đồng ý với bạn. Một vài điều ngay lập tức nhảy ra với tôi là bạn đã cung cấp một ví dụ hơi tiếp tuyến bằng cách đề cập đến "anh chị em" khi OP hỏi về mối quan hệ phân cấp. Có lẽ cũng phong cách viết của bạn có thể được cải thiện. Bạn sử dụng nhiều "...", chúng tôi có xu hướng không sử dụng "..." rất nhiều trong văn bản chính thức, chuyên nghiệp hoặc hướng dẫn. Cũng có một chút dư thừa (ví dụ bạn đề cập, ví dụ, sau đó nói trong ví dụ của bạn). Có lẽ câu trả lời của bạn có thể ngắn gọn hơn và trực tiếp hơn giải quyết câu hỏi OP.
KennyCason
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.