Question Si les applications REST sont supposées être sans état, comment gérez-vous les sessions?


J'ai besoin de quelques éclaircissements. J'ai lu des articles sur REST et créé des applications RESTful. Selon Wikipedia, REST lui-même est défini pour être Transfert d'état représentatif. Je ne comprends donc pas tous ces apatrides gobbledeygook que tout le monde crache.

De wikipedia:

À un moment donné, un client peut soit être en transition entre   états d'application ou "au repos". Un client dans un état de repos est capable de   interagir avec son utilisateur, mais ne crée aucune charge et ne consomme aucun client   stockage sur l'ensemble des serveurs ou sur le réseau.

Est-ce qu'ils disent juste ne pas utiliser le magasin de données de niveau session / application?

Je me rends compte que l'un des objectifs de REST est de rendre l'accès à l'URI cohérent et disponible, par exemple, au lieu de cacher les demandes de pagination à l'intérieur des publications, faisant du numéro de page d'une requête une partie de l'URI GET. Cela a du sens pour moi. Mais il semble que ça ne fait que dépasser non par données client (données de session) devrait jamais être stocké côté serveur.

Et si j'avais une file d'attente de messages et que mon utilisateur voulait lire les messages, mais qu'il les lisait, il voulait bloquer certains messages des expéditeurs pendant la durée de sa session? Ne serait-il pas logique de stocker ceci dans un endroit du côté serveur, et le serveur envoie-t-il uniquement des messages (ou des ID de message) qui n'ont pas été bloqués par l'utilisateur?

Dois-je vraiment envoyer la liste complète des expéditeurs de message à bloquer chaque fois que je demande la nouvelle liste de messages? La liste des messages pertinents pour moi ne devrait pas / ne devrait même pas être une ressource accessible au public en premier lieu.

Encore une fois, essayant juste de comprendre ceci. Quelqu'un S'il vous plaît clarifier.


Mettre à jour:

J'ai trouvé une question de débordement de pile qui a une réponse qui ne m'amène pas tout le chemin: Comment gérer l'état dans REST qui dit que l'état du client qui est important devrait tous être transférés à chaque demande .... Ugg .. semble être beaucoup de frais généraux ... Est-ce vrai?


415
2018-06-23 20:30


origine


Réponses:


L'explication fondamentale est:

Aucun état de session client sur le serveur.

Par apatride, cela signifie que le serveur ne stocke aucun état sur le session client du côté serveur.

le session client est stocké sur le client. Le serveur est sans état signifie que chaque serveur peut servir n'importe quel client à tout moment, il n'y a pas affinité de session ou sessions collantes. Les informations de session pertinentes sont stockées sur le client et transmises au serveur selon les besoins.

Cela n'empêche pas les autres services auxquels le serveur Web s'entretient de conserver l'état des objets métier tels que les paniers d'achat, mais pas de l'état actuel de l'application / de la session du client.

le le client l'état de l'application ne doit jamais être stocké sur le serveur, mais transmis à partir du client à chaque endroit qui en a besoin.

C'est où le ST dans DU REPOS vient de, Transfert d'État. Vous transférez l'état autour au lieu d'avoir le serveur le stocker. C'est le seul moyen de s'adapter à des millions d'utilisateurs simultanés. Si ce n'est que pour des millions de sessions, ce sont des millions de sessions.

La charge de la gestion de session est amorti sur l'ensemble des clients, les clients conservent leur état de session et les serveurs peuvent desservir plusieurs ordres de grandeur ou plus de clients dans un mode sans état.

Même pour un service que vous pensez seulement besoin dans les 10 des milliers d'utilisateurs simultanés, vous devez toujours rendre votre service sans état. Des dizaines de milliers de personnes sont encore des dizaines de milliers et des coûts en temps et en espace seront associés.

Stateless comment le protocole HTTP et le web en général a été conçu pour fonctionner et est une mise en œuvre globale plus simple et vous avez un chemin de code unique au lieu d'un tas de logique côté serveur pour maintenir un groupe d'état de session.

Il y a quelques principes de mise en œuvre très basiques:

Ce sont des principes et non des implémentations, la manière dont vous respectez ces principes peut varier.

En résumé, le cinq principes clés sont:

  1. Donnez à chaque "chose" un ID
  2. Relier les choses ensemble
  3. Utiliser des méthodes standard
  4. Ressources à représentations multiples
  5. Communiquer sans état

Il n'y a rien sur l'authentification ou l'autorisation dans le REST thèse.

Parce qu'il n'y a rien de différent de l'authentification d'une requête RESTful par une autre qui ne l'est pas. L'authentification n'est pas pertinente pour la discussion RESTful.

Expliquer comment créer une application sans état pour vos besoins particuliers est trop large pour StackOverflow.

L'implémentation de l'authentification et de l'autorisation dans le cadre de REST l'est encore plus trop large et diverses approches de la mise en œuvre sont expliquées en détail sur Internet en général.

Les commentaires demandant de l’aide / des informations à ce sujet / doivent juste être signalés comme    Ne sont plus nécessaires.


430
2018-06-23 20:35



L'apatridie signifie que chaque requête HTTP se produit dans un isolement complet. Lorsque le client effectue une requête HTTP, il inclut toutes les informations nécessaires au serveur pour répondre à cette demande. Le serveur ne s'appuie jamais sur les informations des demandes précédentes. Si cette information était importante, le client l'aurait renvoyé dans cette demande. L'apatridie apporte également de nouvelles fonctionnalités. Il est plus facile de distribuer une application sans état sur des serveurs à charge équilibrée. Une application sans état est également facile à mettre en cache.

Il y a en fait deux types d'états. Application Etat qui réside sur le client et l'état des ressources qui réside sur le serveur.

Un service Web doit uniquement prendre en compte l'état de votre application lorsque vous effectuez une demande. Le reste du temps, il ne sait même pas que tu existes. Cela signifie que chaque fois qu'un client effectue une demande, il doit inclure tous les états de l'application dont le serveur aura besoin pour le traiter.

L'état des ressources est le même pour chaque client et sa place est sur le serveur. Lorsque vous téléchargez une image sur un serveur, vous créez une nouvelle ressource: la nouvelle image possède son propre URI et peut être la cible de futures requêtes. Vous pouvez récupérer, modifier et supprimer cette ressource via HTTP.

J'espère que cela aide à différencier ce que signifient l'apatridie et les différents états.


211
2018-06-24 02:56



Est-ce qu'ils disent juste ne pas utiliser le magasin de données de niveau session / application?

Non, ils ne le disent pas d'une manière insignifiante.

Ils disent ne pas définir une "session". Ne vous connectez pas Ne pas se déconnecter Fournissez les informations d'identification avec la demande. Chaque demande est indépendante.

Vous avez toujours des magasins de données. Vous avez toujours l'authentification et l'autorisation. Vous ne perdez pas de temps à établir des sessions et à maintenir l'état de la session.

Le fait est que chaque demande (a) est complètement isolée et (b) peut être trivialement transformée en une ferme de serveurs parallèle géante sans travail réel. Apache ou Squid peuvent passer des demandes RESTful aveuglément et avec succès.

Et si j'avais une file d'attente de messages et que mon utilisateur voulait lire les messages, mais qu'il les lisait, il voulait bloquer certains messages des expéditeurs pendant la durée de sa session?

Si l'utilisateur veut un filtre, il suffit de fournir le filtre sur chaque requête.

Cela n'aurait-il pas un sens de ... faire en sorte que le serveur envoie uniquement des messages (ou des identifiants de message) qui n'ont pas été bloqués par l'utilisateur?

Oui. Fournissez le filtre dans la demande d'URI RESTful.

Dois-je vraiment envoyer la liste complète des expéditeurs de message à bloquer chaque fois que je demande la nouvelle liste de messages?

Oui. Quelle est la taille de cette "liste d'expéditeurs de messages à bloquer"? Une courte liste de PK?

Une requête GET peut être très importante. Si nécessaire, vous pouvez essayer une requête POST même si cela ressemble à une sorte de requête.


69
2018-06-23 20:44



Vous avez absolument raison, soutenir des interactions complètement sans état avec le serveur impose un fardeau supplémentaire au client. Cependant, si vous envisagez de mettre à l'échelle une application, la puissance de calcul des clients est directement proportionnelle au nombre de clients. Par conséquent, la mise à l'échelle d'un grand nombre de clients est beaucoup plus faisable.

Dès que vous mettez un peu de responsabilité sur le serveur pour gérer certaines informations liées aux interactions d'un client spécifique, cette charge peut rapidement augmenter pour consommer le serveur.

C'est un compromis.


30
2018-06-24 02:41



Vue historique de la gestion de l'état de l'application utilisateur

Les sessions au sens traditionnel conservent l'état de l'utilisateur dans l'application à l'intérieur du serveur. Il peut s'agir de la page en cours dans un flux ou de ce qui a été précédemment entré mais pas encore conservé dans la base de données principale.

La raison de ce besoin était le manque de normes du côté client pour maintenir efficacement l’état sans rendre les applications ou les plug-ins spécifiques au client (c’est-à-dire spécifiques au navigateur).

HTML5 et XML Header Request a normalisé au fil du temps la notion de stockage de données complexes, y compris état de l'application de manière standard sur le côté client (c.-à-d. navigateur) sans avoir à faire des allers-retours entre le serveur.

Utilisation générale des services REST

Les services REST sont généralement appelés lorsqu'il y a une transaction à effectuer ou qu'il faut extraire des données.

Les services REST sont destinés à être appelés par l'application côté client et non directement par l'utilisateur final.

Authentification

Pour toute demande adressée au serveur, une partie de la demande doit contenir le jeton d'autorisation. La façon dont il est mis en œuvre est spécifique à l'application, mais en général est soit un BASIC ou CERTIFICATE forme d'authentification.

L'authentification basée sur un formulaire n'est pas utilisée par les services REST. Cependant, comme indiqué ci-dessus, les services REST ne sont pas destinés à être appelés par l'utilisateur, mais par l'application. L'application doit gérer l'obtention du jeton d'authentification. Dans mon cas, j'ai utilisé des cookies avec JASPIC avec OAuth 2.0 pour se connecter à Google pour l'authentification et l'authentification HTTP simple pour les tests automatisés. J'ai aussi utilisé Authentification d'en-tête HTTP via JASPIC pour les tests locaux également (bien que la même approche puisse être effectuée dans SiteMinder)

Conformément à ces exemples, l'authentification est gérée côté client (bien que SiteMinder ou Google stocke la session d'authentification de son côté), rien ne peut être fait à propos de cet état, mais il ne fait pas partie de l'application de service REST.

Requêtes de récupération

Les demandes de récupération dans REST sont GET opérations dans lesquelles une ressource spécifique est demandée et peut être mise en cache. Il n'y a pas besoin de sessions serveur car la requête a tout ce dont elle aurait besoin pour récupérer les données: l'authentification et l'URI.

Scripts de transaction

Comme indiqué ci-dessus, l'application côté client appelle elle-même les services REST ainsi que l'authentification qu'elle gère du côté client.

Qu'est-ce que cela signifie pour les services REST [si cela est fait correctement] est de prendre une seule requête au serveur REST contiendra tout ce qui est nécessaire pour une opération utilisateur unique qui fait tout ce qui est nécessaire dans une seule transaction, un Script de transaction est ce que le modèle est appelé.

Cela se fait par un POST demande habituellement, mais d'autres comme PUT peut également être utilisé.

Beaucoup d'exemples inventés de REST (j'ai moi-même fait cela) ont essayé de suivre autant de ce qui a été défini dans le protocole HTTP, après avoir traversé que j'ai décidé d'être plus pragmatique et je l'ai laissé à GET et POST uniquement. le POST La méthode n'a même pas besoin d'implémenter le modèle POST-REDIRECT-GET.

Néanmoins, comme je l'ai noté plus haut, l'application côté client sera celle qui appelle le service et elle n'appellera que POST demande avec toutes les données quand il le faut (pas à chaque fois). Cela empêche les requêtes constantes au serveur.

Vote

Bien que REST puisse également être utilisé pour les interrogations, je ne le recommanderai que si vous devez l'utiliser en raison de la compatibilité du navigateur. Pour cela j'utiliserais WebSockets que j'avais conçu un Contrat API pour aussi bien. Une autre alternative pour les anciens navigateurs est CometD.


27
2017-07-24 22:53



REST est très abstrait. Il est utile d'avoir de bons exemples simples et concrets.

Prenez par exemple toutes les principales applications de médias sociaux - Tumblr, Instagram, Facebook et Twitter. Ils ont tous une vue à défilement permanent où plus vous défilez vers le bas, plus vous voyez de contenu, de plus en plus loin dans le temps. Cependant, nous avons tous connu ce moment où vous perdez où vous avez défilé, et l'application vous ramène au sommet. Comme si vous quittiez l'application, alors lorsque vous la rouvrez, vous êtes de nouveau au sommet.

La raison en est que le serveur n'a pas stocké votre état de session. Malheureusement, votre position de défilement a été simplement stockée dans la RAM sur le client.

Heureusement, vous n'avez pas à vous reconnecter lorsque vous vous reconnectez, mais cela uniquement parce que votre certificat de connexion également stocké côté client n'a pas expiré. Supprimez et réinstallez l'application et vous devrez vous reconnecter car le serveur n'a pas associé votre adresse IP à votre session.

Vous n'avez pas de session de connexion sur le serveur, car ils respectent REST.


Désormais, les exemples ci-dessus n'impliquent aucun navigateur Web, mais les applications communiquent via HTTPS avec leurs serveurs hôtes. Ce que je veux dire, c’est que REST n’a pas à impliquer les cookies et les navigateurs, etc. Il existe différents moyens de stocker l’état de session côté client.

Mais parlons un peu des navigateurs Web, car cela soulève un autre avantage majeur de REST dont personne ne parle ici.

Si le serveur a essayé de stocker l'état de la session, comment est-il censé identifier chaque client individuel?

Il ne pouvait pas utiliser leur adresse IP, car de nombreuses personnes pouvaient utiliser cette même adresse sur un routeur partagé. Alors comment, alors?

Il ne peut pas utiliser l'adresse MAC pour de nombreuses raisons, notamment parce que vous pouvez être connecté à plusieurs comptes Facebook différents simultanément sur différents navigateurs et à l'application. Un navigateur peut facilement prétendre en être un autre, et les adresses MAC sont aussi faciles à usurper.

Si le serveur doit stocker un état côté client pour vous identifier, il doit le stocker dans la mémoire RAM plus longtemps que le temps nécessaire au traitement de vos demandes, sinon il doit mettre en cache ces données. Les serveurs ont des quantités limitées de RAM et de cache, sans parler de la vitesse du processeur. L'état côté serveur s'ajoute aux trois, exponentiellement. De plus, si le serveur stocke des informations sur vos sessions, il doit les stocker séparément pour chaque navigateur et application avec lesquels vous êtes actuellement connecté, ainsi que pour chaque périphérique que vous utilisez.


Donc ... J'espère que vous voyez maintenant pourquoi REST est si important pour l'évolutivité. J'espère que vous pouvez commencer à comprendre pourquoi l'état de session côté serveur est à l'évolutivité du serveur, ce que les enclumes soudées sont à l'accélération de la voiture.


On se confond en pensant que "état" se réfère, par exemple, aux informations stockées dans une base de données. Non, il fait référence à toute information devant figurer dans la mémoire vive du serveur lorsque vous l'utilisez.


22
2018-01-10 00:37



L'état sans état signifie que l'état du service ne persiste pas entre les demandes suivantes et la réponse. Chaque requête comporte ses propres informations d'identification et est authentifiée individuellement. Mais en étatful chaque demande est connue de toute demande préalable. Toutes les demandes avec état sont orientées session, c'est-à-dire que chaque requête doit connaître et conserver les modifications apportées dans les demandes précédentes.

L'application bancaire est un exemple d'application avec état. Où l'utilisateur se connecte d'abord, puis effectue la transaction et se déconnecte. Si, après la déconnexion, l'utilisateur tente d'effectuer la transaction, il ne pourra pas le faire.

Oui, le protocole http est essentiellement un protocole sans état, mais pour le rendre état nous faisons des cookies HTTP. Donc, est SOAP par défaut. Mais il peut être fait de même état, dépend du cadre que vous utilisez.

HTTP est sans état mais nous pouvons tout de même maintenir la session dans notre application Java en utilisant un mécanisme de suivi de session différent.

Oui, nous pouvons également maintenir la session dans le service Web, que ce soit REST ou SOAP. Il peut être implémenté en utilisant une bibliothèque tierce ou que vous pouvez implémenter par nos propres moyens.

Pris à partir de http://gopaldas.org/webservices/soap/webservice-is-stateful-or-stateless-rest-soap


11
2017-09-04 12:03



Je vois que le problème fondamental ici est de mélanger Session avec Etat. Et tandis que REST spécifie que vous ne devez PAS stocker le Etat sur le serveur, rien ne vous empêche de stocker un utilisateur Session.

Gérer le Etat sur le serveur signifie que votre serveur sait exactement ce que le client fait (quelle page il affiche dans quelle section de l’application). Et c'est ce que vous ne devriez pas avoir à faire.

Je suis d'accord avec les autres personnes pour dire que vous devez conserver le stockage de la session à une taille minimale; et même si c'est du bon sens, cela dépend aussi de l'application. Donc, en bref, vous pouvez toujours conserver une session avec des données mises en cache pour gérer les demandes avec moins de charge sur le serveur et gérer l'authentification en fournissant un jeton d'authentification / accès temporaire à utiliser par le client. Chaque fois que la session / le jeton a expiré, générez-en un nouveau et demandez au client de l'utiliser.

Quelqu'un pourrait argumenter que le client devrait mieux générer le jeton. Je dis que cela fonctionne dans les deux sens, et cela dépend de l'application, et qui va travailler avec l'API.

Garder également certaines données de session sensibles sur le serveur devrait être la bonne façon de faire. Vous ne pouvez pas faire confiance au client pour conserver son panier qui (par exemple) contient un champ nommé "isFreeGift". Ces informations doivent être conservées sur le serveur.

Le lien vidéo fourni par Santanu Dey dans sa réponse est utile. Regardez-le si vous ne l'avez pas fait.

Juste une note: il semble que toutes les réponses déjà données semblent ignorer le fait que certaines opérations pourraient causer une lourde charge sur le serveur. C'est pertinent en termes de consommation d'énergie, de consommation de matériel et de coût (pour les serveurs loués par cycle CPU). Un bon développeur ne doit pas être paresseux dans l'optimisation de son application, même si l'opération peut être effectuée très rapidement sur un processeur moderne sur un serveur loué pour lequel il ne paie pas sa facture d'électricité et de maintenance.

Bien que la question date de quelques années, j'espère que ma réponse sera toujours utile.


9
2018-01-04 00:11



Jetez un oeil à cette présentation.

http://youtu.be/MRxTP-rQ-S8

Selon ce modèle, créer des ressources transitoires pour gérer l'état si nécessaire. Évitez les sessions explicites.


4
2017-12-06 14:08



La différence majeure entre stateless et stateful est que les données sont renvoyées au serveur à chaque fois. En cas d’apatridie, le client doit fournir toutes les informations, il faudra donc passer beaucoup de paramètres dans chaque requête. Dans Stateful, le cliet transmet ces paramètres une fois et ils sont maintenus par le serveur jusqu'à ce qu'ils soient modifiés à nouveau par le client.

IMO, API devrait être sans état, ce qui permet de faire évoluer très rapidement.


3
2018-05-22 12:44