¿Deben los objetos de solicitud / respuesta HTTP ser inmutables?

10

Creo que es seguro decir que la mayoría de las aplicaciones web se basan en el paradigma de solicitud / respuesta. PHP nunca ha tenido una abstracción formal de estos objetos. Un grupo está tratando de cambiar esto: https://github.com/php-fig/fig-standards/blob/master/proposed/http-message.md

Sin embargo, de alguna manera fueron rastreados en el tema de la inmutabilidad. Por un lado, el objeto de solicitud / respuesta generalmente necesita muy pocos cambios durante su ciclo de vida. Por otro lado, el objeto de respuesta en particular a menudo necesita que se agreguen encabezados HTTP.

Además, la inmutabilidad nunca ha tenido éxito en la tierra de PHP.

¿Qué ventajas ve la gente al usar objetos de solicitud / respuesta inmutables?


Supongamos que está devolviendo un objeto json.

$response = new JsonResponse($item);

Agradable y simple Pero resulta que la solicitud era una solicitud de Intercambio de recursos de origen cruzado (CORS). El código que genera la respuesta no debería importarle, pero en algún lugar posterior es un proceso que agregará los encabezados de control de acceso necesarios. ¿Alguna ventaja de mantener la respuesta original y crear una nueva con los encabezados adicionales? ¿O es estrictamente una cuestión de estilo de programación?

El objeto de solicitud es un poco más interesante. Comienza igual:

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

La información inicial no debería necesitar ser cambiada. Sin embargo, a medida que se pasa la solicitud, a menudo es necesario agregar información de procesamiento adicional. Por ejemplo, puede tener un url matcher que decida qué acción se debe ejecutar para una solicitud determinada.

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

En realidad, ejecutar la acción es responsabilidad de un proceso descendente. Podría tener una RequestAttributesCollection mutable que envuelve la solicitud inmutable pero que tiende a ser un poco incómoda en la práctica. También podría tener una solicitud que sea inmutable, excepto para una colección de atributos. Las excepciones también tienden a ser incómodas. ¿Alguna experiencia en el manejo de este tipo de requisitos?

Cerad
fuente
Si es solo la solicitud / respuesta original que necesita, podemos almacenar un clon del objeto que se establece en el c'tor y luego nunca se toca nuevamente. Puede mutar pero aún acceder al original cuando sea necesario. Esto probablemente habría sido mejor IMO.
mpen

Respuestas:

4

¿Qué ventajas ve la gente al usar objetos de solicitud / respuesta inmutables?

Estoy de acuerdo con la declaración de @ MainMa " No estoy seguro de si el ligero beneficio de la legibilidad compensa la posible falta de flexibilidad " y personalmente no veo ningún aspecto práctico y útil de obligar a PHP HTTP Requestobjetos PHP HTTP Responsetemporales u objetos temporales a ser inmutables

¿Alguna experiencia en el manejo de este tipo de requisitos?

  1. El Windows Presentation Foundationmarco de Microsoft introduce el concepto de objetos congelables . Una vez congelados, tales objetos se convierten

    • inmutable (lanzar excepciones cuando se intenta la modificación),
    • más rápido de usar (los captadores de propiedades ya no necesitan tomar decisiones elegantes "¿cuál es mi valor?"),
    • Consumir menos memoria (las estructuras de datos de ayuda interna y cachés, etc. se pueden reducir a su representación más eficiente en tiempo y espacio)
    • y compartible

    Aunque se utiliza como optimización de velocidad de la GUI, el concepto en sí es aplicable también en otros lugares, incluidos sus beneficios

  2. Nancy("Marco ligero, de baja ceremonia, para construir servicios basados ​​en HTTP en .Net y Mono") describe el beneficio de la inmutabilidad en uno de los comentarios de confirmación como

    ... podemos suponer que nuestros cachés son inmutables si están apagados, lo que significa que no tenemos bloqueos para un rendimiento más rápido (aunque el éxito no es masivo) ...

    No he encontrado ninguna otra observación notable de la inmutabilidad, pero el beneficio de objetos reutilizables de respuesta, cacheables pueden aplicarse a los PHPasí

Lo anterior puede parecer respuestas fuera de tema, pero no estoy al tanto de nada más y es por eso que creo que el requisito de inmutabilidad es un problema artificial y más bien una cuestión de preferencia o estilo de codificación, etc.

xmojmr
fuente
1
Gracias. Ambas respuestas fueron informativas. Decidí aceptar el tuyo porque la noción de objetos congelados ayudó a aclarar mi pensamiento. Se crea un objeto inmutable de respuesta congelada, ya que algún punto justo antes de enviar el objeto se clona y descongela. Se pueden agregar grupos de encabezados orientados a la entrega (cachés, cors, etc.). El objeto se puede congelar y enviar en su camino.
Cerad
7

Los objetos inmutables en general tienen varios beneficios.

  • La más importante es lo fácil que es usar objetos inmutables en código ejecutado en paralelo. Esto también explica por qué "la inmutabilidad nunca ha tenido éxito en la tierra de PHP" .

  • La consistencia del estado es más fácil de obtener.

  • Los objetos son fáciles, más naturales para trabajar.

Lo esencial es cuánto debería cambiar el objeto durante su vida útil: cada cambio en un objeto inmutable requiere crear una instancia adicional, que puede ser rápidamente demasiado costosa en términos de memoria (y probablemente también de ciclos de CPU). Esta es también la razón por la cual la mayoría de los lenguajes de programación donde stringes inmutable termina teniendo otra clase para algún tipo de cadenas mutables, como StringBuilderen C #, para responder a situaciones en las que las cadenas se concatenan de muchas partes pequeñas, cada parte se agrega dinámicamente.

En una biblioteca del lado del cliente (enviando una solicitud HTTP y recibiendo una respuesta), tiene sentido hacer que la solicitud y la respuesta HTTP sean inmutables: si bien algunas solicitudes se pueden construir con una interfaz fluida, este no es el uso principal. La respuesta no cambiará de todos modos, por lo que la inmutabilidad tiene sentido.

En una biblioteca del lado del servidor (que recibe una solicitud HTTP y envía una respuesta), aunque la solicitud puede ser inmutable, no estoy seguro de si la respuesta puede serlo. Los datos en sí pueden ser una secuencia (que, para algunas personas, ver más abajo, obliga al objeto de respuesta a ser mutable), y los encabezados pueden agregarse "sobre la marcha" durante la ejecución del script, hasta que la respuesta comience a ser enviado al cliente

En ambos casos, dado que no hay ejecución en paralelo, no estoy seguro de si el ligero beneficio de la legibilidad compensa la posible falta de flexibilidad.

Asegúrese de leer también un artículo más completo de Evert Pot sobre PSR-7 . El artículo explica, entre otros, que uno de los casos en que tal inmutabilidad es problemática es para respuestas largas que deben transmitirse . Personalmente, no veo el punto: en mi humilde opinión, nada prohíbe que un objeto inmutable contenga una secuencia (por ejemplo, un FileReaderobjeto puede ser inmutable incluso si lee un archivo que puede cambiar con el tiempo). El marco Flask de Python utiliza un enfoque diferente cuando se trata de respuestas grandes (o respuestas que toman tiempo en generar) al devolver un iterador.

Arseni Mourzenko
fuente
1
Una ventaja que también vale la pena mencionar IMO es que cuando tiene objetos inmutables, nunca necesita preguntarse si está trabajando con una copia privada, puede cambiar libremente o una referencia propiedad de otro objeto donde los cambios pueden afectar a otros objetos.
Philipp
@Philipp: En mi humilde opinión, una de las mayores deficiencias en Java.NET es la falta de una convención para distinguir entre los métodos que devuelven referencias a nuevos objetos que la persona que llama puede cambiar a voluntad, frente a los que devuelven referencias que están unidas o encapsuladas internamente. estado que puede modificarse para manipular ese estado, y aquellos que devuelven referencias a objetos que pueden o pueden estar unidos al estado interno. No es posible escribir código que sea robusto y eficiente sin saber qué tipo de referencias se supone que deben devolver las cosas, pero no hay una convención que indique eso.
supercat
Gracias por la respuesta. Más o menos confirmó lo que estaba pensando, así que debe ser correcto. Decidí aceptar la respuesta de xmoyxr porque él planteó el concepto de congelar objetos que no había encontrado antes.
Cerad