Je concevais une application Web, puis je me suis arrêté pour réfléchir à la manière dont mon API devrait être conçue comme un service Web RESTful. Pour l'instant, la plupart de mes URI sont génériques et peuvent s'appliquer à diverses applications Web:
GET /logout // destroys session and redirects to /
GET /login // gets the webpage that has the login form
POST /login // authenticates credentials against database and either redirects home with a new session or redirects back to /login
GET /register // gets the webpage that has the registration form
POST /register // records the entered information into database as a new /user/xxx
GET /user/xxx // gets and renders current user data in a profile view
POST /user/xxx // updates new information about user
J'ai le sentiment que je me trompe beaucoup après avoir fouillé sur SO et google.
Commençant par /logout
, peut-être puisque je ne fais pas vraiment GET
rien - il serait peut-être plus approprié de POST
une demande à /logout
, détruisez la session, puis GET
la redirection. Et devrait le /logout
séjour temporaire?
Qu'en est-il de /login
et /register
. Je pourrais changer /register
à /registration
mais cela ne modifie pas le fonctionnement fondamental de mon service - s'il pose des problèmes plus profonds.
Je remarque maintenant que je n'expose jamais un /user
Ressource. Peut-être que cela pourrait être utilisé d'une manière ou d'une autre. Par exemple, prenons l'utilisateur myUser
:
foo.com/user/myUser
ou
foo.com/user
L'utilisateur final n'a pas besoin de cette verbosité supplémentaire dans l'URI. Cependant, lequel est le plus attrayant visuellement?
J'ai remarqué quelques autres questions ici sur SO à ce sujet REST entreprise, mais j'apprécierais vraiment quelques conseils sur ce que j'ai présenté ici si possible).
Merci!
PDATE:
J'aimerais aussi avoir des avis sur:
/user/1
contre
/user/myUserName
Une chose ressort en particulier comme non-REST-FUL: l'utilisation d'une requête GET pour se déconnecter.
(de http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Safe_methods )
Certaines méthodes (par exemple, HEAD, GET, OPTIONS et TRACE) sont définies comme étant sûres, ce qui signifie qu'elles sont uniquement destinées à la récupération d'informations et ne doivent pas modifier l'état du serveur. En d'autres termes, ils ne devraient pas avoir d'effets secondaires, au-delà d'effets relativement inoffensifs tels que la journalisation, la mise en cache, la diffusion de bannières publicitaires ou l'incrémentation d'un compteur Web. [...]
[... H] andling [des requêtes GET] du serveur n'est techniquement d'aucune façon limitée. Par conséquent, une programmation négligente ou délibérée peut entraîner des modifications non triviales sur le serveur. Ceci est déconseillé, car cela peut poser des problèmes pour la mise en cache Web, les moteurs de recherche et autres agents automatisés [...]
En ce qui concerne la déconnexion et la redirection, vous pouvez avoir une publication dans votre URI de déconnexion, donnant une réponse 303 redirigée vers la page de post-déconnexion.
http://en.wikipedia.org/wiki/Post/Redirect/Get
http://en.wikipedia.org/wiki/HTTP_3
Modifier pour résoudre les problèmes de conception d'URL:
"Comment concevoir mes ressources?" C'est une question importante pour moi. "comment puis-je concevoir mes URL?" est une considération dans deux domaines:
Les URL que les utilisateurs verront ne doivent pas être trop laides ni significatives, si possible; Si vous souhaitez que les cookies soient envoyés à certaines ressources mais pas à d'autres, vous devrez structurer vos chemins d'accès et les chemins d'accès aux cookies.
Si JRandomUser
veut consulter son propre profil et que vous souhaitez que l'URL soit plus jolie que foo.com/user/JRandomUser
Ou foo.com/user/(JRandom's numeric user id here)
, vous pouvez créer une URL distincte, uniquement pour l'utilisateur. à leur propre information:
GET foo.com/profile /*examines cookies to figure out who
* is logged in (SomeUser) and then
* displays the same response as a
* GET to foo.com/users/SomeUser.
*/
Je dirais que l'ignorance est beaucoup plus facile que la sagesse à ce sujet, mais voici quelques considérations sur la conception des ressources:
RESTful peut être utilisé comme guide pour la construction d'URL et vous pouvez créer des ressources sessions et tilisateurs:
GET /session/new
Obtient la page Web contenant le formulaire de connexionPOST /session
Authentifie les informations d'identification par rapport à la base de donnéesDELETE /session
Détruit la session et redirige vers /GET /users/new
Obtient la page Web contenant le formulaire d'inscriptionPOST /users
Enregistre les informations saisies dans la base de données en tant que nouveau/utilisateur/xxxGET /users/xxx
// récupère et restitue les données utilisateur actuelles dans une vue de profilPOST /users/xxx
// met à jour les nouvelles informations sur l'utilisateurCeux-ci peuvent être au pluriel ou au singulier (je ne suis pas sûr de celui qui est correct). J'ai généralement utilisé /users
Pour une page d'index utilisateur (comme prévu) et /sessions
Pour voir qui est connecté (comme prévu).
Utiliser le nom dans l'URL au lieu d'un nombre (/users/43
Vs /users/joe
) Est généralement motivé par le désir d'être plus convivial avec les utilisateurs ou les moteurs de recherche, sans aucune exigence technique. Soit c'est bien, mais je vous recommande d'être cohérent.
Je pense que si vous utilisez les options register/login/logout ou sign(in|up|out)
, cela ne fonctionnera pas aussi bien avec la terminologie reposante.
les sessions ne sont pas reposantes
Oui je sais. Cela se fait, généralement avec OAuth, mais en réalité, les sessions ne sont pas reposantes. Vous ne devriez pas avoir de ressource/login/logout principalement parce que vous ne devriez pas avoir de sessions.
Si vous allez le faire, rendez-le RESTful. Les ressources sont des noms et/login et/logout ne sont pas des noms. Je voudrais aller avec/session. Cela rend la création et la suppression plus naturelles.
POST vs GET pour les sessions est facile. Si vous envoyez utilisateur/mot de passe sous forme de variables, j'utiliserais POST car je ne souhaite pas que le mot de passe soit envoyé avec l'URI. Il apparaîtra dans les journaux et sera éventuellement exposé. Vous courez également le risque d’échec logiciel sur les limitations de GET args.
J'utilise généralement l'authentification de base ou aucune autorisation avec les services REST.
Création d'utilisateurs
C'est une ressource, vous ne devriez donc pas avoir besoin de/vous inscrire.
Quel type d'identifiant utiliser est une question difficile. Vous devez penser à imposer l'unicité, à la réutilisation d'anciens identifiants supprimés. Par exemple, vous ne souhaitez pas utiliser ces identifiants en tant que clés étrangères sur un backend si les identifiants vont être recyclés (dans la mesure du possible). Vous pouvez toutefois rechercher une conversion d'identifiant externe/interne afin d'atténuer les exigences du backend.
Je vais simplement parler de mon expérience d’intégration de divers REST services Web pour mes clients, qu’ils soient utilisés pour des applications mobiles ou pour la communication entre serveurs, ainsi que de la construction REST pour les autres. Voici quelques observations que j'ai rassemblées de l'AP REST d'autres personnes) ainsi que de celles que nous avons construites nous-mêmes:
GET/register // obtient la page Web contenant le formulaire d'inscription
GET/logout // détruit la session et redirige vers /[.____.unsetPOST/login // authentifie les informations d'identification par rapport à la base de données et redirige la maison vers une nouvelle session ou redirige vers /login
En tant que REST sont conçus en tant que services, des fonctions telles que la connexion et la déconnexion renvoient normalement le résultat de réussite/échec (normalement au format de données JSON ou XML) que le consommateur interpréterait ensuite. Cette interprétation pourrait inclure redirection vers la page Web appropriée que vous avez mentionnée
GET/register // récupère la page Web contenant le formulaire d'inscription POST/register // enregistre les informations saisies dans la base de données sous la forme d'un nouveau /user/xxx .
Ce sont quelques points de ce que j'ai traité. J'espère que cela pourra vous aider.
En ce qui concerne l’implémentation de votre REST, voici l’implémentation typique que j’ai rencontrée:
GET/logout
Exécutez la déconnexion dans le backend et renvoyez JSON pour indiquer le succès/l'échec de l'opération.
POST /login
Soumettez les informations d'identification au serveur. Retourner le succès/échec. En cas de succès, le jeton de session ainsi que les informations de profil sont normalement renvoyés.
POST /register
Soumettez votre inscription au serveur. Retourner le succès/échec. En cas de succès, le traitement est normalement identique à la connexion réussie ou vous pouvez choisir de vous enregistrer en tant que service distinct.
GET /user/xxx
Obtenir le profil utilisateur et renvoyer le format de données JSON pour le profil de l'utilisateur
POST/user/xxx // renommé en POST /updateUser/xxx
Publiez les informations de profil mises à jour au format JSON et mettez à jour les informations dans le backend. Renvoyer le succès/l'échec à l'appelant
Je crois que c'est une approche RESTful à l'authentification. Pour vous connecter, utilisez HttpPut
. Cette méthode HTTP peut être utilisée pour la création lorsque la clé est fournie et que les appels répétés sont idempotents. Pour LogOff, vous indiquez le même chemin sous la méthode HttpDelete
. Aucun verbe utilisé. Une pluralisation correcte des collections. Les méthodes HTTP supportent l'objectif.
[HttpPut]
[Route("sessions/current")]
public IActionResult LogIn(LogInModel model) { ... }
[HttpDelete]
[Route("sessions/current")]
public IActionResult LogOff() { ... }
Si vous le souhaitez, vous pouvez remplacer le courant par le courant.
Je recommanderais d'utiliser une URL de compte d'utilisateur similaire à Twitter, où l'URL du compte de l'utilisateur serait quelque chose comme foo.com/myUserName
comme vous pouvez accéder à mon compte Twitter avec l’URL https://Twitter.com/joelbyler
Je ne suis pas d'accord sur la déconnexion nécessitant un POST. Dans le cadre de votre API, si vous souhaitez conserver une session, un identifiant de session sous la forme d'un UUID peut être utilisé pour suivre un utilisateur et confirmer que l'action entreprise est autorisée. Alors même un GET peut transmettre l’identifiant de session à la ressource.
En bref, je vous recommande de garder les choses simples, les URL doivent être courtes et mémorables.