Os objetos HTTP Request / Response devem ser imutáveis?

10

Eu acho que é seguro dizer que a maioria dos aplicativos da Web é baseada no paradigma de solicitação / resposta. O PHP nunca teve uma abstração formal desses objetos. Um grupo está tentando mudar isso: https://github.com/php-fig/fig-standards/blob/master/proposed/http-message.md

No entanto, eles meio que ficaram de fora da questão da imutabilidade. Por um lado, o objeto de solicitação / resposta geralmente precisa de muito pouca mudança durante seu ciclo de vida. Por outro lado, o objeto de resposta em particular geralmente precisa que cabeçalhos HTTP sejam adicionados.

Além disso, a imutabilidade nunca realmente pegou na terra do PHP.

Que vantagens as pessoas vêem no uso de objetos imutáveis ​​de solicitação / resposta?


Vamos supor que você esteja retornando um objeto json.

$response = new JsonResponse($item);

Agradável e simples. Mas acontece que a solicitação era uma solicitação de compartilhamento de recursos de origem cruzada (CORS). O código que gera a resposta não deve se importar, mas em algum ponto a jusante é um processo que adicionará os cabeçalhos de controle de acesso necessários. Alguma vantagem em manter a resposta original e criar uma nova com os cabeçalhos adicionais? Ou é estritamente uma questão de estilo de programação.

O objeto de solicitação é um pouco mais interessante. Começa da mesma forma:

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

As informações iniciais não precisam ser alteradas. No entanto, à medida que a solicitação é transmitida, geralmente é necessário adicionar informações de processamento adicionais. Por exemplo, você pode ter um correspondente de URL que decide qual ação deve ser executada para uma determinada solicitação.

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

A execução real da ação é de responsabilidade de um processo de downstream. Você pode ter um RequestAttributesCollection mutável que agrupa a solicitação imutável, mas que na prática costuma ser um pouco estranho. Você também pode ter uma solicitação imutável, exceto por uma coleção de atributos. Exceções também tendem a ser estranhas. Alguma experiência em lidar com esses tipos de requisitos?

Cerad
fonte
Se é apenas a solicitação / resposta original que você precisa, podemos armazenar um clone do objeto que é definido no c'tor e nunca mais é tocado. Você pode mudar, mas ainda acessar o original sempre que necessário. Provavelmente teria sido melhor IMO.
MPEN

Respostas:

4

Que vantagens as pessoas vêem no uso de objetos imutáveis ​​de solicitação / resposta?

Concordo com a afirmação da @ MainMa " Não tenho certeza se o pequeno benefício da legibilidade compensa a possível falta de flexibilidade " e, pessoalmente, não vejo nenhum aspecto prático e útil de forçar PHP HTTP Requestobjetos PHP HTTP Responsetemporários ou objetos temporários a serem imutáveis

Alguma experiência em lidar com esses tipos de requisitos?

  1. A Windows Presentation Foundationestrutura da Microsoft introduz o conceito de objetos que podem ser congelados . Uma vez congelados, esses objetos se tornam

    • imutável (lança exceções quando se tenta modificar),
    • mais rápido de usar (os getters de propriedades não precisam mais tomar decisões sofisticadas sobre "qual é o meu valor?"),
    • consumir menos memória (estruturas internas de dados auxiliares e caches etc. podem ser reduzidos à sua representação mais eficiente em termos de tempo e espaço)
    • e compartilhável

    Embora seja usado como otimização de velocidade da GUI, o próprio conceito é aplicável também em outros lugares, incluindo seus benefícios

  2. Nancy("Estrutura leve e de cerimônia baixa para a criação de serviços baseados em HTTP em .Net e Mono") descreve o benefício da imutabilidade em um dos comentários de confirmação, como

    ... podemos assumir que nossos caches são imutáveis ​​se estiverem desativados, o que significa que não temos bloqueios com desempenho mais rápido (embora o acerto não seja grande) ...

    I não encontrou quaisquer outros comentários dignos de nota sobre a imutabilidade, mas o benefício de, objetos de resposta armazenáveis reutilizáveis podem ser aplicadas a PHPbem

O exemplo acima pode parecer respostas fora do tópico, mas não tenho conhecimento de mais nada e é por isso que acho que o requisito de imutabilidade é um problema artificial e, em vez disso, é uma questão de preferência ou estilo de codificação etc.

xmojmr
fonte
1
Obrigado. Ambas as respostas foram informativas. Decidi aceitar o seu porque a noção de congelamento de objetos ajudou a esclarecer meu pensamento. Um objeto de resposta congelado imutável é criado, como em algum momento antes de enviar o objeto, é clonado e descongelado. Grupos de cabeçalhos orientados à entrega (caches, cors etc.) podem ser adicionados. O objeto pode ser congelado e enviado a caminho.
CERAD
7

Objetos imutáveis ​​em geral têm vários benefícios.

  • O mais importante é como é fácil usar objetos imutáveis ​​no código executado em paralelo. Isso também explica por que "a imutabilidade nunca realmente pegou na terra do PHP" .

  • A consistência do estado é mais fácil de obter.

  • Os objetos são fáceis e mais naturais de se trabalhar.

O essencial é quanto o objeto deve mudar durante sua vida útil - toda mudança em um objeto imutável exige a criação de uma instância adicional, que pode rapidamente ser muito cara em termos de memória (e provavelmente também ciclos da CPU). É também por isso que a maioria das linguagens de programação onde stringé imutável acaba tendo outra classe para algum tipo de sequência mutável, como StringBuilderem C #, para responder a situações em que as sequências são concatenadas de muitas partes pequenas, cada parte adicionada dinamicamente.

Em uma biblioteca do lado do cliente (enviando uma solicitação HTTP e recebendo uma resposta), faz sentido tornar a solicitação e a resposta HTTP imutáveis: embora algumas solicitações possam ser construídas com uma interface fluente, esse não é o uso principal. A resposta não será alterada, então a imutabilidade faz sentido.

Em uma biblioteca do lado do servidor (recebendo uma solicitação HTTP e enviando uma resposta), embora a solicitação possa ser imutável, não tenho certeza se a resposta pode ser. Os dados em si podem ser um fluxo (que, para algumas pessoas - veja abaixo - força o objeto de resposta a ser mutável), e os cabeçalhos podem ser adicionados "on the fly" durante a execução do script, até que a resposta comece. ser enviado ao cliente.

Nos dois casos, como não há execução paralela, não tenho certeza se o pequeno benefício da legibilidade compensa a possível falta de flexibilidade.

Leia também um artigo mais completo da Evert Pot sobre o PSR-7 . O artigo explica, entre outros, que um dos casos em que essa imutabilidade é problemática é para respostas longas que devem ser transmitidas . Pessoalmente, não vejo o ponto: IMHO, nada proíbe que um objeto imutável contenha um fluxo (por exemplo, um FileReaderobjeto pode ser imutável, mesmo que ele leia um arquivo que pode mudar com o tempo). A estrutura Flask do Python usa uma abordagem diferente quando se trata de respostas grandes (ou respostas que levam tempo para serem geradas) retornando um iterador.

Arseni Mourzenko
fonte
1
Uma vantagem que também vale a pena mencionar à IMO é que, quando você tem objetos imutáveis, nunca precisa se perguntar se está trabalhando com uma cópia privada. Você pode alterar livremente ou uma referência pertencente a outro objeto, onde as alterações podem afetar outros objetos.
Philipp
@ Philipp: IMHO, uma das maiores deficiências do Java.NET é a falta de uma convenção para distinguir entre métodos que retornam referências a novos objetos que o chamador pode alterar à vontade, versus aqueles que retornam referências anexadas ou encapsuladas em interno estado que pode ser modificado para manipular esse estado e aqueles que retornam referências a objetos que podem ou podem ser anexados ao estado interno. Não é possível escrever um código que seja robusto e eficiente sem saber que tipos de referências as coisas devem retornar, mas não há convenção para indicar isso.
Supercat
Obrigado pela resposta. Isso praticamente confirmou o que eu estava pensando, então deve estar certo. Decidi aceitar a resposta do xmoyxr porque ele levantou o conceito de congelamento de objetos que eu não havia encontrado antes.
CERAD