Gli oggetti HTTP Request / Response dovrebbero essere immutabili?


10

Penso che sia sicuro affermare che la maggior parte delle applicazioni Web si basa sul paradigma richiesta / risposta. PHP non ha mai avuto un'astrazione formale di questi oggetti. Un gruppo sta cercando di cambiare questo: https://github.com/php-fig/fig-standards/blob/master/proposed/http-message.md

Tuttavia, hanno una sorta di tracciamento laterale sul problema dell'immutabilità. Da un lato, l'oggetto richiesta / risposta generalmente necessita di pochissime modifiche durante il suo ciclo di vita. D'altra parte, l'oggetto risposta in particolare ha spesso bisogno di aggiungere intestazioni HTTP.

Inoltre, l'immutabilità non ha mai veramente preso piede nella terra di PHP.

Quali vantaggi vedono le persone nell'uso di oggetti di richiesta / risposta immutabili?


Supponiamo che tu stia restituendo un oggetto json.

$response = new JsonResponse($item);

Bello e semplice. Ma risulta che la richiesta era una richiesta CORS (Cross-Origin Resource Sharing). Il codice che genera la risposta non dovrebbe interessare, ma da qualche parte a valle è un processo che aggiungerà le necessarie intestazioni Access-Control. Qualche vantaggio nel mantenere la risposta originale e crearne una nuova con le intestazioni aggiuntive? O è strettamente una questione di stile di programmazione.

L'oggetto richiesta è un po 'più interessante. Inizia allo stesso modo:

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

Le informazioni iniziali non devono essere modificate. Tuttavia, poiché la richiesta viene trasmessa, spesso è necessario aggiungere ulteriori informazioni di elaborazione. Ad esempio, potresti avere un URL matcher che decide quale azione deve essere eseguita per una determinata richiesta.

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

L'esecuzione effettiva dell'azione è responsabilità di un processo a valle. Potresti avere un RequestAttributesCollection mutevole che avvolge la richiesta immutabile ma che nella pratica tende a essere un po 'imbarazzante. Potresti anche avere una richiesta immutabile ad eccezione di una raccolta di attributi. Anche le eccezioni tendono a essere imbarazzanti. Qualche esperienza sulla gestione di questo tipo di requisiti?


Se è solo la richiesta / risposta originale di cui hai bisogno, possiamo archiviare un clone dell'oggetto che viene impostato nel c'tor e non viene mai più toccato. Puoi mutare ma accedere comunque all'originale ogni volta che è necessario. Questo probabilmente sarebbe stato meglio IMO.
mpen

Risposte:


4

Quali vantaggi vedono le persone nell'uso di oggetti di richiesta / risposta immutabili?

Concordo con l'affermazione di @ MainMa " Non sono sicuro che il leggero vantaggio della leggibilità compensi la possibile mancanza di flessibilità " e personalmente non vedo alcun aspetto pratico e utile di forzare PHP HTTP Requestoggetti PHP HTTP Responsetemporanei o oggetti temporanei come immutabili

Qualche esperienza sulla gestione di questo tipo di requisiti?

  1. Il Windows Presentation Foundationframework di Microsoft introduce il concetto di oggetti congelabili . Una volta congelati, tali oggetti diventano

    • immutabile (genera eccezioni quando si tenta di apportare modifiche),
    • più veloce da usare (i getter di proprietà non devono più prendere decisioni "qual è il mio valore?"),
    • consumando meno memoria (le strutture di dati degli helper interni, le cache ecc. possono essere ridotte alla loro rappresentazione più efficiente in termini di tempo e spazio)
    • e condivisibile

    Sebbene sia usato come ottimizzazione della velocità della GUI, il concetto stesso è applicabile anche altrove, compresi i suoi vantaggi

  2. Nancy("Quadro leggero, a bassa cerimonia, per la creazione di servizi basati su HTTP su .Net e Mono") descrive i vantaggi dell'immutabilità in uno dei commenti di commit come

    ... possiamo supporre che le nostre cache siano immutabili se sono disattivate, il che significa che non abbiamo blocchi con prestazioni così più veloci (anche se il colpo non è massiccio) ...

    Non ho trovato nessun altro commento degno di nota sull'immutabilità, ma è possibile applicare PHPanche il beneficio di oggetti riutilizzabili e memorizzabili nella cache

Quanto sopra può sembrare una risposta fuori tema, ma non sono a conoscenza di nient'altro ed è per questo che penso che il requisito di immutabilità sia un problema artificiale e piuttosto una questione di preferenza o stile di codifica ecc.


1
Grazie. Entrambe le risposte sono state informative. Ho deciso di accettare il tuo perché l'idea di congelare oggetti mi ha aiutato a chiarire il mio pensiero. Viene creato un oggetto di risposta congelato immutabile, come alcuni punti appena prima di inviare l'oggetto vengono clonati e sbloccati. È possibile aggiungere gruppi di intestazioni orientate alla consegna (cache, cors, ecc.). L'oggetto può quindi essere congelato e inviato sulla sua strada.
Cerad,

7

Gli oggetti immutabili in generale hanno diversi vantaggi.

  • Il più importante è quanto è facile usare oggetti immutabili nel codice eseguito in parallelo. Questo spiega anche perché "l'immutabilità non ha mai veramente preso piede nella terra del PHP" .

  • La coerenza statale è più facile da ottenere.

  • Gli oggetti sono facili, più naturali con cui lavorare.

L'essenziale è quanto l'oggetto dovrebbe cambiare durante il suo ciclo di vita: ogni modifica a un oggetto immutabile richiede la creazione di un'istanza aggiuntiva, che può rapidamente essere troppo costosa in termini di memoria (e probabilmente anche cicli della CPU). Questo è anche il motivo per cui la maggior parte dei linguaggi di programmazione in cui stringè immutabile finisce per avere un'altra classe per una sorta di stringhe mutabili, come StringBuilderin C #, per rispondere a situazioni in cui le stringhe sono concatenate da molte piccole parti, ciascuna parte aggiunta in modo dinamico.

In una libreria lato client (invio di una richiesta HTTP e ricezione di una risposta), ha senso rendere immutabili la richiesta e la risposta HTTP: mentre alcune richieste potrebbero essere costruite con un'interfaccia fluida, questo non è il principale utilizzo. La risposta non verrà comunque modificata, quindi l'immutabilità ha un senso.

In una libreria lato server (ricezione di una richiesta HTTP e invio di una risposta), mentre la richiesta può essere immutabile, non sono sicuro che la risposta possa esserlo. I dati stessi possono essere un flusso (che, per alcune persone - vedi sotto - impone che l'oggetto di risposta sia mutabile), e le intestazioni stesse possono essere aggiunte "al volo" durante l'esecuzione dello script, fino a quando la risposta inizia a essere inviato al cliente.

In entrambi i casi, dato che non esiste alcuna esecuzione in parallelo, non sono sicuro che il leggero vantaggio della leggibilità compensi la possibile mancanza di flessibilità.

Assicurati di leggere anche un articolo più completo di Evert Pot sulla PSR-7 . L'articolo spiega, tra l'altro, che uno dei casi in cui tale immutabilità è problematica è per le risposte lunghe che dovrebbero essere trasmesse in streaming . Personalmente, non vedo il punto: IMHO, nulla impedisce a un oggetto immutabile di contenere un flusso (ad esempio, un FileReaderoggetto può essere immutabile anche se legge un file che può cambiare nel tempo). Il framework Flask di Python utilizza un approccio diverso quando si tratta di risposte di grandi dimensioni (o risposte che richiedono tempo per la generazione) restituendo un iteratore.


1
Un vantaggio che vale anche la pena menzionare IMO è che quando si hanno oggetti immutabili non è mai necessario chiedersi se si sta lavorando con una copia privata, è possibile modificare liberamente o un riferimento di proprietà di un altro oggetto in cui le modifiche potrebbero influire su altri oggetti.
Philipp

@Philipp: IMHO, una delle maggiori carenze in Java.NET è la mancanza di una convenzione per distinguere tra metodi che restituiscono riferimenti a nuovi oggetti che il chiamante può cambiare a piacimento, rispetto a quelli che restituiscono riferimenti a cui sono collegati o incapsulano interni stato che può essere modificato per manipolare quello stato e quelli che restituiscono riferimenti a oggetti che possono o possono essere collegati allo stato interno. Non è possibile scrivere codice che sia robusto ed efficiente senza sapere che tipo di riferimenti dovrebbero restituire le cose, ma non esiste una convenzione per indicarlo.
supercat

Grazie per la risposta. Ha praticamente confermato ciò che stavo pensando, quindi deve essere giusto. Ho deciso di accettare la risposta di xmoyxr perché ha sollevato il concetto di congelamento di oggetti che non avevo mai incontrato prima.
Cerad,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.