API REST: en-têtes HTTP personnalisés et paramètres d'URL

96

Quand utilisez-vous des en-têtes HTTP personnalisés dans la partie requête d'une API REST?

Exemple:

Souhaitez-vous jamais utiliser

GET /orders/view 
(custom HTTP header) CLIENT_ID: 23

au lieu de

GET /orders/view/client_id/23 or 
GET /orders/view/?client_id=23
Vasile Cotovanu
la source

Réponses:

123

L'URL indique la ressource elle-même. Un « client » est une ressource qui peut être mise en pratique , devrait donc faire partie de l'URL de base: /orders/view/client/23.

Les paramètres ne sont que cela, pour paramétrer l'accès à la ressource. Cela vient notamment en jeu avec les messages et les recherches: /orders/find?q=blahblah&sort=foo. Il y a une ligne fine entre les paramètres et les sous-ressources: /orders/view/client/23/active versus /orders/view/client/23?show=active. Je recommande le style de sous-ressource et les paramètres de réserve pour les recherches.

Étant donné que chaque point de terminaison représente un transfert d'état (pour modifier le mnémonique), les en-têtes personnalisés ne doivent être utilisés que pour les choses qui n'impliquent pas le nom de la ressource (l'url), l'état de la ressource (le corps) ou les paramètres directement affectant la ressource (paramètres). Cela laisse de vraies métadonnées sur la demande d'en-têtes personnalisés.

HTTP a une très large sélection d'en-têtes qui couvrent presque tout ce dont vous aurez besoin. Là où j'ai vu des en-têtes personnalisés apparaître, c'est dans une requête système à système fonctionnant au nom d'un utilisateur. Le système proxy validera l'utilisateur et ajoutera " X-User: userid" aux en-têtes et utilisera les informations d'identification du système pour atteindre le point final. Le système de réception valide que les informations d'identification du système sont autorisées à agir au nom de l'utilisateur, puis valide que l'utilisateur est autorisé à effectuer l'action.

Nialscorva
la source
Merci pour une réponse aussi complète! Utiliseriez-vous toujours X-User pour une API mobile où le risque d'avoir un proxy maléfique (qui supprime l'en-tête) est toujours élevé?
Vasile Cotovanu
1
Non, l'utilisation de X-User que j'ai mentionnée est dans le système aux connexions système où le système agit pour le compte d'un tiers. Par exemple, l'utilisateur U parle au serveur A. Le serveur A présente des informations d'identification au serveur B avec un en-tête X-User pour dire "Utilisez mes informations d'identification pour vérifier que je suis autorisé à effectuer cette action au nom de l'utilisateur U." Cela se produit dans les architectures orientées services, et vous utilisez généralement HTTPS. Une plate-forme mobile devrait presque toujours être l'utilisateur lui-même agissant et utiliser les informations d'identification à la première personne appropriées pour la transaction.
Nialscorva
7
Le troisième paragraphe est l'une des réponses les plus informatives que j'ai lues sur SO ;-)
Alistair77
1
@Nialscorva Excellente explication! Que faire si je souhaite que l'utilisateur interagisse avec mon API via un conteneur autorisé (comme mon application mobile)? Ce que je fais maintenant, c'est que mon application mobile n'est pas autorisée à effectuer une action seule et ni l'utilisateur final. Les deux informations d'identification doivent être présentes si l'utilisateur est prêt à effectuer une action.
bolbol
6

Les en-têtes personnalisés présentent les avantages suivants:

  • Peut être lu facilement par les outils / scripts réseau (authentification, méta info, ...)
  • Protège les URL de tout élément de sécurité (plus sûr, pas dans les caches de navigateur / proxy)
  • Garde les URL plus propres: permet une meilleure mise en cache des ressources
Christophe Roussy
la source
ils peuvent également être supprimés / filtrés en silence par des mandataires
fusi
@fusi bon point ... voici le sujet à ce sujet: stackoverflow.com/questions/20820572/…
Christophe Roussy
5

Je n'utiliserais un en-tête personnalisé que lorsqu'il n'y a pas d'autre moyen de transmettre des informations par standard ou par convention. Darren102 explique la manière typique de transmettre cette valeur. Votre API sera beaucoup plus conviviale en utilisant des versets de modèles typiques utilisant des en-têtes personnalisés, ce qui ne veut pas dire que vous n'aurez pas de cas pour les utiliser, mais qu'ils devraient être le dernier recours et quelque chose qui n'est pas déjà géré par la spécification HTTP.

poursuivre
la source
Tout à fait d'accord ... ne réinventez jamais la roue s'il existe une manière standard d'accomplir une tâche.
Alessandro Santini
5

Quand utilisez-vous ... des en-têtes HTTP dans la partie requête d'une API REST?

Authentification: GUID, authentification de base, jetons personnalisés, etc., par exemple, authentification de base avec un jeton Guid pour l'API REST au lieu du nom d'utilisateur / mot de passe

Si vous êtes impliqué dans la transmission de jetons ou d'autres informations de type authentification entre des domaines couverts par PCI-DSS ou d'autres règles de sécurité, vous devrez peut-être également enterrer des paramètres car certaines réglementations exigent explicitement que les éléments d'authentification restent en dehors des URL qui pourraient être relues de manière triviale (à partir de historiques du navigateur, journaux de proxy, etc.).

user3038458
la source
1

Il n'y a pas de norme pour REST mais la méthode acceptée serait

GET /orders/view/23

Ne pas utiliser les en-têtes personnalisés et, par conséquent, la vue 23 après suppose être l'id, vous auriez donc une fonction qui prend l'id et donc produit uniquement cette information.

darren102
la source
1

Je n'utiliserais pas d'en-têtes personnalisés car vous ne savez pas si des mandataires les transmettront. L'URL est la voie à suivre.

GET / commandes / vue / client / 23

Antony Scott
la source
1
Je ne recommanderais pas non plus les en-têtes personnalisés, mais les proxies défectueux ne sont pas la raison. Le proxy est cassé, il devrait être corrigé.
Julian Reschke
1

Certainement OK:

GET /orders/view/client_id/23 or 
GET /orders/view/?client_id=23

Aussi correct:

GET /orders/view/23 or 

Je pense que ce serait OK aussi:

POST /orders/view 
(custom HTTP header) CLIENT_ID: 23
paulsm4
la source
La réponse POST REST-ful doit être un HTTP 303 avec l'en-tête Location défini sur quelque chose comme "/ orders / view / 23".
Rich Remer
0

Vous pouvez utiliser des en-têtes personnalisés pour inclure plus d'informations sur une demande partiellement traitée, étant donné que l' enveloppe n'est pas une bonne pratique. Les en-têtes sont sécurisés .

Anwar Husain
la source