Dove dovremmo mettere le azioni di ricerca?
In GET /search/:text
. Ciò restituirà un array JSON contenente le corrispondenze, ogni corrispondenza contenente l'album a cui appartiene. Questo ha senso, perché il cliente potrebbe essere interessato non alla traccia stessa, ma all'intero album (immagina di essere alla ricerca di una canzone che, a tuo avviso, era nello stesso album di quella che ricordi il nome).
non sarà così buono restituire gli ID parent con ciascuno di essi. Ho sbagliato?
Le singole tracce possono contenere l'album. Ciò garantirà l'uniformità della rappresentazione della traccia se è possibile ottenere una traccia tramite un album o tramite la ricerca (nessun album qui).
Che è migliore?
Come precedentemente affermato, includere l'album ha senso. Mentre il terzo punto (con il relativo URI) può essere interessante in alcuni casi (non devi pensare al modo in cui dovrebbe essere formato l'URI), ha uno svantaggio di non fornire esplicitamente l'album. Il quarto punto corregge questo. Se vedi il vantaggio di avere l'URI relativo nella risposta, puoi combinare i punti 3 e 4.
O forse sono stupido?
Scegliere buoni URI non è un compito facile, soprattutto perché non esiste un'unica risposta corretta. Se sviluppi il client contemporaneamente all'API, potrebbe aiutarti a visualizzare meglio come utilizzare l'API. Detto questo, altre persone potrebbero preferire altri usi a cui non stavi pensando durante lo sviluppo dell'API.
Un aspetto che può essere problematico è il modo in cui organizzi i dati internamente, ovvero l'utilizzo di una gerarchia. Dal tuo commento, ti stai chiedendo a cosa dovrebbe contenere una risposta GET /artist/1/album/10/song/3/comment/23
, che mostra una visione molto orientata agli alberi. Ciò può comportare alcuni problemi durante l'estensione del sistema in un secondo momento. Per esempio:
- Cosa succede se una canzone non ha un album?
- E se un album avesse più artisti?
- Cosa succede se si desidera aggiungere una funzione che consenta di commentare gli album?
- Cosa succede se ci dovrebbero essere commenti di commenti?
- eccetera.
Questo è essenzialmente il problema che ho spiegato nel mio blog : una rappresentazione ad albero ha troppe limitazioni per essere efficacemente utilizzata in molti casi.
Cosa succede se distruggi la gerarchia? Vediamo.
GET /albums/:albumId
restituisce un JSON contenente le meta informazioni sull'album (come l'anno in cui è stato pubblicato o l'URI del JPEG che mostra la copertina dell'album) e una serie di tracce. Per esempio:
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"
}
...
]
}
Perché includo, ad esempio, la lunghezza di ciascuna traccia? Perché immagino che il cliente che mostra un album possa essere interessato elencando le tracce per titolo, ma anche mostrare la lunghezza di ciascuna traccia, la maggior parte dei clienti lo fa. D'altra parte, potrei non mostrare il compositore o gli artisti per ogni traccia, perché decido che queste informazioni non sono necessarie a questo livello. Ovviamente, le tue scelte potrebbero essere diverse.
GET /tracks/:trackId
restituisce le informazioni su una traccia specifica. Poiché non esiste più una gerarchia, non è necessario indovinare l'album o l'artista: l'unica cosa che devi sapere è l'identificatore della traccia stessa.
O forse no? E se fosse possibile specificarlo per nome con 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
}
}
Ora guarda più da vicino albums
; cosa vedi? Giusto, non uno, ma due album. Se hai una gerarchia, non puoi farlo (a meno che non duplichi il record).
GET /comments/:objectGid
. Potresti aver individuato i brutti GUID nelle risposte. Questi GUID consentono di identificare l'entità nel database al fine di eseguire attività che possono essere applicate ad album, artisti o brani. Come commentare.
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"
}
]
Il commento fa riferimento all'oggetto in questione, rendendo possibile accedervi quando si accede al commento al di fuori del suo contesto (ad esempio quando si moderano gli ultimi commenti GET /comments/latest
).
Nota che questo non significa che dovresti evitare qualsiasi forma di gerarchia nella tua API. Ci sono casi in cui ha senso. Come regola generale:
Se la risorsa non ha senso al di fuori del contesto della sua risorsa padre, utilizzare la gerarchia.
Se la risorsa può vivere (1) da sola o (2) in un contesto di risorse padre di tipi diversi o (3) avere più genitori, la gerarchia non deve essere utilizzata.
Ad esempio, le righe di un file non hanno senso al di fuori del contesto di un file, quindi:
GET /file/:fileId
e:
GET /file/:fileId/line/:lineIndex
stanno bene.
SongSearchResult
, va bene, suppongo. Ma che dire degli URL? Devo fornireparentID
ogni oggetto e usarlo come parametro GET o parte normale dell'URL? E se avessi profondità> 2?/artist/1/album/10/song/3/comment/23
- è folle fornire ogni id di artista, album e canzonecomment
nell'oggetto, ma ho sentito che è una strada da percorrere, ma non è disgustoso ?!