Les objets de requête / réponse HTTP doivent-ils être immuables?

10

Je pense qu'il est sûr de dire que la plupart des applications Web sont basées sur le paradigme de demande / réponse. PHP n'a jamais eu d'abstraction formelle de ces objets. Un groupe essaie de changer cela: https://github.com/php-fig/fig-standards/blob/master/proposed/http-message.md

Cependant, ils ont en quelque sorte été mis de côté sur la question de l'immuabilité. D'une part, l'objet de demande / réponse nécessite généralement très peu de changement au cours de son cycle de vie. D'un autre côté, l'objet de réponse en particulier a souvent besoin d'ajouter des en-têtes HTTP.

De plus, l'immuabilité n'a jamais vraiment fait son chemin au pays de PHP.

Quels avantages les gens voient-ils à utiliser des objets de demande / réponse immuables?


Supposons que vous renvoyiez un objet json.

$response = new JsonResponse($item);

Agréable et simple. Mais il s'avère que la demande était une demande de partage de ressources d'origine croisée (CORS). Le code qui génère la réponse ne devrait pas se soucier mais quelque part en aval est un processus qui ajoutera les en-têtes de contrôle d'accès nécessaires. Un avantage à conserver la réponse d'origine et à en créer une nouvelle avec les en-têtes supplémentaires? Ou est-ce strictement une question de style de programmation.

L'objet de requête est un peu plus intéressant. Cela commence de la même façon:

$request = new Request('incoming request information including uri and headers');

Les informations initiales ne doivent pas être modifiées. Cependant, à mesure que la demande est transmise, il est souvent nécessaire d'ajouter des informations de traitement supplémentaires. Par exemple, vous pouvez avoir un adaptateur d'URL qui décide quelle action doit être exécutée pour une demande donnée.

$request->setAttribute('action',function() {});

L'exécution effective de l'action est la responsabilité d'un processus en aval. Vous pouvez avoir un RequestAttributesCollection modifiable qui encapsule la demande immuable mais qui a tendance à être un peu gênant dans la pratique. Vous pouvez également avoir une demande immuable, à l'exception d'une collection d'attributs. Les exceptions ont également tendance à être gênantes. Avez-vous une expérience dans la gestion de ce type d'exigences?

Cerad
la source
S'il ne s'agit que de la demande / réponse d'origine dont vous avez besoin, nous pouvons stocker un clone de l'objet qui est défini dans le c'tor et qui n'est plus jamais touché. Vous pouvez muter, mais toujours accéder à l'original en cas de besoin. Cela aurait probablement été mieux l'OMI.
mpen

Réponses:

4

Quels avantages les gens voient-ils à utiliser des objets de demande / réponse immuables?

Je suis d'accord avec la déclaration de @ MainMa " Je ne sais pas si le léger avantage de la lisibilité compense le manque de flexibilité possible " et personnellement je ne vois aucun aspect pratique et utile de forcer PHP HTTP Requestles objets PHP HTTP Responsetemporaires ou les objets temporaires à être immuables

Avez-vous une expérience dans la gestion de ce type d'exigences?

  1. Le Windows Presentation Foundationcadre de Microsoft introduit le concept d' objets congelables . Une fois gelés, ces objets deviennent

    • immuable (lever des exceptions en cas de tentative de modification),
    • plus rapide à utiliser (les getters de propriété n'ont plus besoin de prendre des décisions fantaisistes "quelle est ma valeur?"),
    • consommer moins de mémoire (les structures de données auxiliaires internes et les caches, etc. peuvent être réduites à leur représentation la plus efficace en termes de temps et d'espace)
    • et partageable

    Bien qu'il soit utilisé comme optimisation de la vitesse de l'interface graphique, le concept lui-même est également applicable ailleurs, y compris ses avantages

  2. Nancy(«Cadre léger et peu cérémonieux pour la création de services basés sur HTTP sur .Net et Mono») décrit l'avantage de l'immuabilité dans l' un des commentaires de validation comme

    ... nous pouvons supposer que nos caches sont immuables s'ils sont désactivés, ce qui signifie que nous n'avons pas de verrous donc des performances plus rapides (bien que le hit ne soit pas massif) ...

    Je ne trouve pas d'autres commentaires notables sur immuabilité, mais l'avantage des objets de réponse réutilisables, cacheable peut appliquer à PHPmême

Les réponses ci-dessus peuvent ressembler à des réponses hors sujet, mais je ne suis au courant de rien d'autre et c'est pourquoi je pense que l'exigence d'immuabilité est un problème artificiel et plutôt une question de préférence ou de style de codage, etc.

xmojmr
la source
1
Merci. Les deux réponses étaient informatives. J'ai décidé d'accepter la vôtre car la notion de congélation d'objets a aidé à clarifier ma pensée. Un objet de réponse figé immuable est créé, comme un point juste avant d'envoyer l'objet est cloné et non gelé. Des groupes d'en-têtes orientés livraison (caches, cors, etc.) peuvent être ajoutés. L'objet peut ensuite être gelé et envoyé sur son chemin.
Cerad
7

Les objets immuables ont en général plusieurs avantages.

  • Le plus important est la facilité d'utilisation des objets immuables dans le code exécuté en parallèle. Cela explique également pourquoi "l'immuabilité n'a jamais vraiment pris racine au pays de PHP" .

  • La cohérence des états est plus facile à obtenir.

  • Les objets sont faciles à utiliser, plus naturels.

L'essentiel est de savoir dans quelle mesure l'objet doit changer au cours de sa durée de vie - chaque modification apportée à un objet immuable nécessite de créer une instance supplémentaire, qui peut rapidement être trop coûteuse en termes de mémoire (et probablement de cycles CPU également). C'est aussi pourquoi la plupart des langages de programmation où stringest immuable finit par avoir une autre classe pour une sorte de chaînes mutables, comme StringBuilderen C #, pour répondre aux situations où les chaînes sont concaténées à partir de nombreuses petites parties, chaque partie étant ajoutée dynamiquement.

Dans une bibliothèque côté client (envoi d'une demande HTTP et réception d'une réponse), il est logique de rendre la demande et la réponse HTTP immuables: bien que certaines demandes puissent être générées avec une interface fluide, ce n'est pas l'usage principal. La réponse ne sera pas modifiée de toute façon, donc l'immuabilité est logique.

Dans une bibliothèque côté serveur (recevoir une requête HTTP et envoyer une réponse), alors que la requête peut être immuable, je ne sais pas si la réponse peut l'être. Les données elles-mêmes peuvent être un flux (qui, pour certaines personnes - voir ci-dessous - oblige l'objet de réponse à être mutable), et les en-têtes eux-mêmes peuvent être ajoutés «à la volée» pendant l'exécution du script, jusqu'à ce que la réponse commence à être envoyé au client.

Dans les deux cas, étant donné qu'il n'y a pas d'exécution en parallèle, je ne sais pas si le léger avantage de lisibilité compense le manque éventuel de flexibilité.

Assurez-vous de lire également un article plus complet d'Evert Pot sur le PSR-7 . L'article explique, entre autres, qu'un des cas où une telle immuabilité est problématique concerne les réponses longues qui devraient être diffusées . Personnellement, je ne vois pas l'intérêt: à mon humble avis, rien n'interdit à un objet immuable de contenir un flux (par exemple, un FileReaderobjet peut être immuable même s'il lit un fichier qui peut évoluer dans le temps). Le framework Flask de Python utilise une approche différente en ce qui concerne les réponses volumineuses (ou les réponses dont la génération prend du temps) en renvoyant un itérateur.

Arseni Mourzenko
la source
1
Un avantage qui mérite également d'être mentionné est que lorsque vous avez des objets immuables, vous n'avez jamais besoin de vous demander si vous travaillez avec une copie privée, vous pouvez modifier librement ou une référence appartenant à un autre objet où les modifications peuvent affecter d'autres objets.
Philipp
@Philipp: À mon humble avis, l'une des plus grandes lacunes de Java.NET est l'absence de convention pour distinguer les méthodes qui renvoient des références à de nouveaux objets que l'appelant peut modifier à volonté, par rapport à celles qui renvoient des références qui sont attachées ou encapsulent des internes état qui peut être modifié pour manipuler cet état, et ceux qui renvoient des références à un objet qui peut ou peut être attaché à l'état interne. Il n'est pas possible d'écrire du code qui est robuste et efficace sans savoir quelles sortes de références les choses sont censées retourner, mais il n'y a pas de convention pour l'indiquer.
supercat
Merci d'avoir répondu. Cela a à peu près confirmé ce que je pensais, donc cela doit être juste. J'ai décidé d'accepter la réponse de xmoyxr car il a évoqué le concept de congélation d'objets que je n'avais pas rencontrés auparavant.
Cerad