Où devrions-nous placer l'action de recherche?
Dans GET /search/:text
. Cela renverra un tableau JSON contenant les correspondances, chaque correspondance contenant l'album auquel il appartient. Cela a du sens, car le client peut être intéressé non pas par le morceau lui-même, mais par l'ensemble de l'album (imaginez que vous recherchez une chanson qui, selon vous, se trouvait dans le même album que celui dont vous vous souvenez du nom).
ce ne sera pas si bon de renvoyer des identifiants parents avec chacun. Ai-je tort?
Les pistes individuelles peuvent contenir l'album. Cela garantira que la représentation des pistes est uniforme si vous pouvez obtenir une piste soit par le biais d'un album, soit par la recherche (pas d'album ici).
Ce qui est mieux?
Comme indiqué précédemment, y compris l'album est logique. Alors que le troisième point (avec l'URI relatif) peut être intéressant dans certains cas (vous n'avez pas à penser à la façon dont l'URI doit être formé), il présente l'inconvénient de ne pas fournir explicitement l'album. Le quatrième point corrige cela. Si vous voyez l'avantage d'avoir l'URI relatif dans la réponse, vous pouvez combiner les points 3 et 4.
Ou peut-être que je suis stupide?
Choisir de bons URI n'est pas une tâche facile, d'autant plus qu'il n'y a pas de bonne réponse unique. Si vous développez le client en même temps que l'API, cela peut vous aider à mieux visualiser comment l'API pourrait être utilisée. Cela étant dit, d'autres personnes peuvent alors préférer d'autres utilisations auxquelles vous ne pensiez pas lors du développement de l'API.
Un aspect qui peut être problématique est la façon dont vous organisez les données en interne, c'est-à-dire l'utilisation d'une hiérarchie. À partir de votre commentaire, vous vous demandez à quoi devrait contenir une réponse GET /artist/1/album/10/song/3/comment/23
, qui montre une vision très arborescente. Cela peut entraîner quelques problèmes lors de l'extension ultérieure du système. Par exemple:
- Et si une chanson n'a pas d'album?
- Et si un album avait plusieurs artistes?
- Que faire si vous souhaitez ajouter une fonctionnalité qui permet de commenter des albums?
- Et s'il devait y avoir des commentaires de commentaires?
- etc.
C'est essentiellement le problème que j'ai expliqué dans mon blog : une représentation arborescente a trop de limitations pour être utilisée efficacement dans de nombreux cas.
Que se passe-t-il si vous détruisez la hiérarchie? Voyons voir.
GET /albums/:albumId
renvoie un JSON contenant les méta-informations sur l'album (comme l'année où il a été publié ou l'URI du JPEG montrant la couverture de l'album) et un tableau de pistes. Par exemple:
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"
}
...
]
}
Pourquoi dois-je inclure, par exemple, la longueur de chaque piste? Parce que j'imagine que le client montrant un album peut être intéressé en listant les pistes par titre, mais aussi montrer la longueur de chaque piste - la plupart des clients le font. En revanche, je ne peux pas montrer le (s) compositeur (s) ou l'artiste (s) pour chaque morceau, car je décide que cette information n'est pas nécessaire à ce niveau. De toute évidence, vos choix peuvent être différents.
GET /tracks/:trackId
renvoie les informations sur une piste spécifique. Puisqu'il n'y a plus de hiérarchie, vous n'avez pas besoin de deviner l'album ou l'artiste: la seule chose que vous devez vraiment savoir est l'identifiant du morceau lui-même.
Ou peut-être même pas? Et si vous pouvez le spécifier par son nom 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
}
}
Maintenant, regardez de plus près albums
; que vois-tu? Bon, pas un, mais deux albums. Si vous avez une hiérarchie, vous ne pouvez pas le faire (sauf si vous dupliquez l'enregistrement).
GET /comments/:objectGid
. Vous avez peut-être repéré les GUID laids dans les réponses. Ces GUID permettent d'identifier l'entité à travers la base de données afin d'effectuer des tâches qui peuvent être appliquées à des albums, des artistes ou des pistes. Telles que des commentaires.
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"
}
]
Le commentaire fait référence à l'objet concerné, permettant d'y accéder lors de l'accès au commentaire en dehors de son contexte (par exemple lors de la modération des derniers commentaires GET /comments/latest
).
Notez que cela ne signifie pas que vous devez éviter toute forme de hiérarchie dans votre API. Il y a des cas où cela a du sens. En règle générale:
Si la ressource n'a aucun sens en dehors du contexte de sa ressource parent, utilisez la hiérarchie.
Si la ressource peut vivre (1) seule ou (2) dans un contexte de ressources parent de différents types ou (3) avoir plusieurs parents, la hiérarchie ne doit pas être utilisée.
Par exemple, les lignes d'un fichier n'ont aucun sens en dehors du contexte d'un fichier, donc:
GET /file/:fileId
et:
GET /file/:fileId/line/:lineIndex
vont bien.
SongSearchResult
, c'est bien, je suppose. Mais qu'en est-il des URL? Dois-je fournirparentID
chaque objet et l'utiliser comme paramètre GET ou comme partie normale de l'url? Et si j'ai une profondeur> 2?/artist/1/album/10/song/3/comment/23
- il est insensé de fournir chaque identifiant d'artiste, d'album et de chanson dans uncomment
objet, mais j'ai entendu dire que c'était un chemin à parcourir, mais n'est-ce pas dégoûtant?!restangular
est construite dessus) n'est pas si bonne./artists/foo/albums/qux
et/artists/bar/albums/qux
peuvent parfaitement identifier la même ressource d'album. En d'autres termes, le composant de chemin dans un URI représente une hiérarchie de graphe , pas nécessairement une hiérarchie d' arbre , ce qui le rend approprié pour représenter non seulement des catégories mais aussi des balises./artists/foo/albums/qux/comments/7
. "Et s'il devait y avoir des commentaires de commentaires?" De même:/artists/foo/albums/qux/song/5/comments/2/comments/8
.