Di mana kita harus meletakkan tindakan pencarian?
Dalam GET /search/:text
. Ini akan mengembalikan susunan JSON yang berisi kecocokan, setiap kecocokan yang berisi album miliknya. Ini masuk akal, karena klien mungkin tertarik bukan pada trek itu sendiri, tetapi seluruh album (bayangkan bahwa Anda sedang mencari lagu yang, Anda yakin, ada di album yang sama dengan yang Anda ingat namanya).
tidak akan baik untuk mengembalikan id orang tua dengan masing-masing begitu. Apakah aku salah?
Masing-masing trek dapat berisi album. Ini akan memastikan bahwa representasi trek seragam jika Anda bisa mendapatkan trek baik melalui album atau melalui pencarian (tidak ada album di sini).
Mana yang lebih baik?
Seperti yang dinyatakan sebelumnya, termasuk album masuk akal. Meskipun poin ketiga (dengan URI relatif) dapat menarik dalam beberapa kasus (Anda tidak harus memikirkan tentang bagaimana URI harus dibentuk), ia memiliki kelemahan karena tidak menyediakan album secara eksplisit. Poin keempat mengoreksi ini. Jika Anda melihat manfaat memiliki URI relatif dalam respons, Anda dapat menggabungkan poin 3 dan 4.
Atau mungkin saya bodoh?
Memilih URI yang baik bukanlah tugas yang mudah, terutama karena tidak ada jawaban yang benar. Jika Anda mengembangkan klien pada saat yang sama dengan API, mungkin membantu Anda untuk memvisualisasikan lebih baik bagaimana API dapat digunakan. Karena itu, orang lain mungkin lebih suka penggunaan lain yang tidak Anda pikirkan saat mengembangkan API.
Aspek yang mungkin bermasalah adalah bagaimana Anda mengatur data secara internal, yaitu penggunaan hierarki. Dari komentar Anda, Anda bertanya-tanya apa yang harus berisi tanggapan GET /artist/1/album/10/song/3/comment/23
, yang menunjukkan visi yang sangat berorientasi pohon. Ini dapat menyebabkan beberapa masalah saat memperpanjang sistem nanti. Contohnya:
- Bagaimana jika sebuah lagu tidak memiliki album?
- Bagaimana jika sebuah album memiliki beberapa artis?
- Bagaimana jika Anda ingin menambahkan fitur yang memungkinkan untuk mengomentari album?
- Bagaimana jika harus ada komentar komentar?
- dll.
Ini pada dasarnya adalah masalah yang saya jelaskan di blog saya : representasi pohon memiliki terlalu banyak keterbatasan untuk digunakan secara efektif dalam banyak kasus.
Apa yang terjadi jika Anda menghancurkan hierarki? Ayo lihat.
GET /albums/:albumId
mengembalikan JSON yang berisi informasi meta tentang album (seperti tahun ketika diterbitkan atau URI dari JPEG yang menunjukkan sampul album) dan serangkaian trek. Sebagai contoh:
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"
}
...
]
}
Mengapa saya memasukkan, misalnya, panjang setiap trek? Karena saya membayangkan bahwa klien yang menunjukkan album mungkin tertarik dengan membuat daftar lagu berdasarkan judul, tetapi juga menunjukkan panjang setiap lagu — kebanyakan klien melakukannya. Di sisi lain, saya tidak boleh menunjukkan komposer atau artis untuk setiap lagu, karena saya memutuskan bahwa informasi ini tidak diperlukan pada tingkat ini. Jelas, pilihan Anda mungkin berbeda.
GET /tracks/:trackId
mengembalikan informasi tentang trek tertentu. Karena tidak ada hierarki lagi, Anda tidak perlu menebak album atau artis: satu-satunya hal yang benar-benar harus Anda ketahui adalah pengidentifikasi trek itu sendiri.
Atau mungkin bahkan tidak? Bagaimana jika Anda dapat menentukan namanya dengan nama 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
}
}
Sekarang lihat lebih dekat albums
; apa yang kamu lihat? Benar, bukan satu, tapi dua album. Jika Anda memiliki hierarki, Anda tidak bisa melakukan itu (kecuali jika Anda menduplikasi catatan).
GET /comments/:objectGid
. Anda mungkin telah melihat GUID yang jelek dalam respons. GUID tersebut memungkinkan untuk mengidentifikasi entitas di seluruh basis data untuk melakukan tugas yang dapat diterapkan pada album, atau artis, atau trek. Seperti berkomentar.
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"
}
]
Komentar mereferensikan objek yang bersangkutan, sehingga memungkinkan untuk pergi ketika mengakses komentar di luar konteksnya (misalnya ketika memoderasi komentar terbaru melalui GET /comments/latest
).
Perhatikan bahwa ini tidak berarti Anda harus menghindari segala bentuk hierarki di API Anda. Ada kasus di mana itu masuk akal. Sebagai aturan praktis:
Jika sumber daya tidak masuk akal di luar konteks sumber daya induknya, gunakan hierarki.
Jika sumber daya dapat hidup (1) sendiri atau (2) dalam konteks sumber daya orang tua dari berbagai jenis atau (3) memiliki banyak orang tua, hierarki tidak boleh digunakan.
Misalnya, baris file tidak masuk akal di luar konteks file, jadi:
GET /file/:fileId
dan:
GET /file/:fileId/line/:lineIndex
baik-baik saja.
SongSearchResult
, tidak apa-apa, saya kira. Tapi bagaimana dengan URL? Haruskah saya memberikanparentID
setiap objek dan menggunakannya sebagai parameter-GET atau bagian normal dari url? Bagaimana jika saya memiliki kedalaman> 2?/artist/1/album/10/song/3/comment/23
- Ini gila untuk memberikan setiap id artis, album dan lagu dalamcomment
objek, tapi saya dengar itu adalah cara untuk pergi, tetapi bukankah ini dsigusting ?!