Chúng ta nên đặt hành động tìm kiếm ở đâu?
Trong GET /search/:text
. Điều này sẽ trả về một mảng JSON chứa các trận đấu, mọi trận đấu có chứa album mà nó thuộc về. Điều này có ý nghĩa, bởi vì khách hàng có thể không quan tâm đến bản nhạc, mà toàn bộ album (hãy tưởng tượng rằng bạn đang tìm kiếm một bài hát mà bạn tin là trong cùng một album với bài bạn nhớ tên).
Sẽ không tốt nếu trả lại id cha với mỗi cái như vậy. Tôi có lầm không?
Các bản nhạc riêng lẻ có thể chứa album. Điều này sẽ đảm bảo rằng đại diện theo dõi là thống nhất nếu bạn có thể nhận được một bản nhạc thông qua một album hoặc thông qua tìm kiếm (không có album ở đây).
Cái nào tốt hơn?
Như đã nêu trước đây, bao gồm cả album có ý nghĩa. Mặc dù điểm thứ ba (với URI tương đối) có thể thú vị trong một số trường hợp (bạn không phải suy nghĩ về cách hình thành URI), nhưng nó có một nhược điểm là không cung cấp rõ ràng album. Điểm thứ tư sửa lỗi này. Nếu bạn thấy lợi ích của việc có URI tương đối trong phản hồi, bạn có thể kết hợp điểm 3 và 4.
Hay có lẽ tôi bị câm?
Chọn URI tốt không phải là một nhiệm vụ dễ dàng, đặc biệt là vì không có câu trả lời đúng duy nhất. Nếu bạn phát triển ứng dụng khách cùng lúc với API, nó có thể giúp bạn hình dung rõ hơn cách sử dụng API. Điều này đang được nói, những người khác sau đó có thể thích các cách sử dụng khác mà bạn không nghĩ đến khi phát triển API.
Một khía cạnh có thể có vấn đề là cách bạn tổ chức dữ liệu trong nội bộ, tức là việc sử dụng hệ thống phân cấp. Từ nhận xét của bạn, bạn đang tự hỏi những gì nên chứa một phản ứng GET /artist/1/album/10/song/3/comment/23
, điều này cho thấy một tầm nhìn rất hướng về cây. Điều này có thể dẫn đến một vài vấn đề khi mở rộng hệ thống sau này. Ví dụ:
- Nếu một bài hát không có album thì sao?
- Điều gì nếu một album có nhiều nghệ sĩ?
- Điều gì nếu bạn muốn thêm một tính năng mà có thể nhận xét album?
- Điều gì nếu có ý kiến của ý kiến?
- v.v.
Đây thực chất là vấn đề tôi đã giải thích trong blog của mình : một đại diện cho cây có quá nhiều hạn chế để được sử dụng hiệu quả trong nhiều trường hợp.
Điều gì xảy ra nếu bạn phá hủy hệ thống phân cấp? Hãy xem nào.
GET /albums/:albumId
trả về một JSON chứa thông tin meta về album (chẳng hạn như năm khi nó được xuất bản hoặc URI của JPEG hiển thị bìa album) và một loạt các bản nhạc. Ví dụ:
GET /albums/151
{
"id": 151,
"gid": "dbd3cec7-b927-423f-894b-742c4c7b54ce",
"name": "Yellow Submarine",
"year": 1969,
"genre": "Psychedelic rock",
"artists": ["John Lennon", "Paul McCartney", ...],
"tracks": [
{
"id": 90224,
"title": "Yellow Submarine",
"length": "2:40"
},
{
"id": 83192,
"title": "Only a Northern Song",
"length": "3:24"
}
...
]
}
Tại sao tôi bao gồm, ví dụ, độ dài của mỗi bản nhạc? Bởi vì tôi tưởng tượng rằng khách hàng đang hiển thị một album có thể quan tâm bằng cách liệt kê các bản nhạc theo tiêu đề, nhưng cũng hiển thị độ dài của mỗi bản nhạc mà hầu hết các khách hàng làm. Mặt khác, tôi không thể hiển thị (các) nhà soạn nhạc hoặc nghệ sĩ cho mỗi bản nhạc, vì tôi quyết định rằng thông tin này không cần thiết ở cấp độ này. Rõ ràng, sự lựa chọn của bạn có thể khác nhau.
GET /tracks/:trackId
trả về thông tin về một bản nhạc cụ thể Vì không còn phân cấp nữa, bạn không cần phải đoán album hoặc nghệ sĩ: điều duy nhất bạn thực sự phải biết là định danh của bản nhạc.
Hoặc thậm chí có thể không? Điều gì nếu bạn có thể chỉ định nó theo tên với GET /tracks/:trackName
?
GET /tracks/Only%20a%20Northern%20Song
{
"id": 83192,
"gid": "8d9c4311-9d7b-40a4-8aeb-4fe96247fe2b",
"title": "Only a Northern Song",
"writers": ["George Harrison"],
"artists": ["John Lennon", "Paul McCartney", "Ringo Starr"],
"length": "3:24",
"record-date": 1967,
"albums": [151, 164],
"soundtrack": {
"uri": "http://audio.example.com/tracks/static/83192.mp3",
"alias": "Beatles - Only a Northern Song.mp3",
"length-bytes": 3524667,
"allow-streaming": true,
"allow-download": false
}
}
Bây giờ nhìn gần hơn albums
; bạn thấy gì? Phải, không phải một, mà là hai album. Nếu bạn có một hệ thống phân cấp, bạn không thể làm điều đó (trừ khi bạn sao chép bản ghi).
GET /comments/:objectGid
. Bạn có thể đã phát hiện ra các GUID xấu xí trong các câu trả lời. Những GUID đó cho phép xác định thực thể trên cơ sở dữ liệu để thực hiện các tác vụ có thể được áp dụng cho album hoặc nghệ sĩ hoặc bản nhạc. Chẳng hạn như bình luận.
GET /comments/8d9c4311-9d7b-40a4-8aeb-4fe96247fe2b
[
{
"author": {
"id": 509931,
"display-name": "Arseni Mourzenko"
},
"text": "What a great song! (And I'm proud of the usefulness of my comment)",
"concerned-object": "/tracks/83192"
}
]
Nhận xét tham chiếu đến đối tượng liên quan, làm cho nó có thể đi đến nó khi truy cập bình luận bên ngoài ngữ cảnh của nó (ví dụ khi kiểm duyệt các bình luận mới nhất thông qua GET /comments/latest
).
Lưu ý rằng điều này không có nghĩa là bạn nên tránh mọi hình thức phân cấp trong API của mình. Có những trường hợp nó có ý nghĩa. Như một quy luật của:
Nếu tài nguyên không có ý nghĩa bên ngoài bối cảnh của tài nguyên mẹ, hãy sử dụng phân cấp.
Nếu tài nguyên có thể sống một mình (1) hoặc (2) trong bối cảnh tài nguyên gốc thuộc các loại khác nhau hoặc (3) có nhiều cha mẹ, thì không nên sử dụng hệ thống phân cấp.
Chẳng hạn, các dòng của một tệp không có ý nghĩa gì ngoài ngữ cảnh của một tệp, vì vậy:
GET /file/:fileId
và:
GET /file/:fileId/line/:lineIndex
tốt thôi.
SongSearchResult
, nó ổn, tôi giả sử. Nhưng còn URL thì sao? Tôi có nên cung cấp choparentID
từng đối tượng và sử dụng nó làm tham số GET hoặc phần bình thường của url không? Nếu tôi có độ sâu> 2 thì sao?/artist/1/album/10/song/3/comment/23
- thật điên rồ khi cung cấp mọi id của nghệ sĩ, album và bài hát trongcomment
đối tượng, nhưng tôi nghe nói đó là một cách để đi, nhưng không phải là khó hiểu?!