190 votes

Quelle est la meilleure méthode RESTful pour retourner le nombre total d'éléments dans un objet ?

Je développe un service API REST pour un grand site de réseautage social dans lequel je suis impliqué. Jusqu'à présent, cela fonctionne très bien. Je peux émettre des GET , POST , PUT y DELETE à des URL d'objets et affectent mes données. Cependant, ces données sont paginées (limitées à 30 résultats à la fois).

Quel serait le meilleur moyen RESTful d'obtenir le nombre total de membres, par exemple, via mon API ?

Actuellement, j'envoie des requêtes à une structure URL comme la suivante :

  • /api/membres - Renvoie une liste de membres (30 à la fois comme indiqué ci-dessus)
  • /api/membres/1 - Affecte un seul membre, en fonction de la méthode de requête utilisée

Ma question est la suivante : comment puis-je utiliser une structure URL similaire pour obtenir le nombre total de membres dans mon application ? Il est évident qu'en demandant seulement le id (similaire à l'API Graph de Facebook) et le comptage des résultats serait inefficace car seule une tranche de 30 résultats serait renvoyée.

15voto

adnan kamili Points 1113

Je recommanderais d'ajouter des en-têtes, par exemple :

HTTP/1.1 200

Pagination-Count: 100
Pagination-Page: 5
Pagination-Limit: 20
Content-Type: application/json

[
  {
    "id": 10,
    "name": "shirt",
    "color": "red",
    "price": "$23"
  },
  {
    "id": 11,
    "name": "shirt",
    "color": "blue",
    "price": "$25"
  }
]

Pour plus de détails, voir :

https://github.com/adnan-kamili/rest-api-response-format

Pour le fichier swagger :

https://github.com/adnan-kamili/swagger-response-template

13voto

Lepidopteron Points 625

À partir de "X-"-Préfixe a été déprécié. (voir : https://www.rfc-editor.org/rfc/rfc6648 )

Nous avons trouvé que les "Accept-Ranges" étaient la meilleure solution pour cartographier la pagination : https://www.rfc-editor.org/rfc/rfc7233#section-2.3 Les "unités de portée" peuvent être des "octets" ou des "jetons". Les deux ne représentent pas un type de données personnalisé. (voir : https://www.rfc-editor.org/rfc/rfc7233#section-4.2 ) Il est toutefois précisé que

Les implémentations HTTP/1.1 PEUVENT ignorer les fourchettes spécifiées à l'aide d'autres unités.

Ce qui signifie que l'utilisation d'unités de portée personnalisées n'est pas contraire au protocole, mais qu'elle PEUT être ignorée.

De cette façon, nous devrions définir Accept-Ranges sur "members" ou tout autre type d'unité à distance auquel nous nous attendons. De plus, il faudrait également définir le Content-Range à l'intervalle actuel. (voir : https://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.12 )

Quoi qu'il en soit, je m'en tiendrais à la recommandation de la RFC7233 ( https://www.rfc-editor.org/rfc/rfc7233#page-8 ) pour envoyer un 206 au lieu d'un 200 :

Si toutes les conditions préalables sont remplies, le serveur prend en charge la gamme
pour la ressource cible, et la ou les plages spécifiées sont
valide et satisfaisable (tel que défini à la section 2.1), le serveur DEVRAIT
envoyer une réponse 206 (Contenu partiel) avec une charge utile contenant un
ou plus de représentations partielles qui correspondent à l'image satisfaisante
demandées, telles que définies à la section 4.

Nous aurions donc les champs d'en-tête HTTP suivants :

Pour un contenu partiel :

206 Partial Content
Accept-Ranges: members
Content-Range: members 0-20/100

Pour un contenu complet :

200 OK
Accept-Ranges: members
Content-Range: members 0-20/20

4voto

questioner Points 11

Que diriez-vous d'un nouveau point final > /api/members/count qui appelle simplement Members.Count() et renvoie le résultat ?

3voto

willcodejavaforfood Points 20365

Il semble plus simple d'ajouter un

GET
/api/members/count

et renvoie le nombre total de membres

2voto

Vahe Hovhannisyan Points 133

Parfois, les frameworks (comme $resource/AngularJS) requièrent un tableau comme résultat de la requête, et vous ne pouvez pas vraiment avoir une réponse comme {count:10,items:[...]} dans ce cas, je stocke "count" dans responseHeaders.

P. S. En fait, vous pouvez le faire avec $resource/AngularJS, mais cela nécessite quelques ajustements.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X