web-dev-qa-db-ja.com

HTTPリクエスト/レスポンスオブジェクトは不変ですか?

ほとんどのWebアプリケーションは要求/応答パラダイムに基づいていると言っても安全だと思います。 PHPは、これらのオブジェクトの正式な抽象化を行ったことはありません。あるグループがこれを変更しようとしています: https://github.com/php-fig/fig-standards/blob/ master/proposed/http-message.md

しかし、彼らは不変性の問題についてはある程度傍観されていました。一方では、要求/応答オブジェクトは通常、ライフサイクル中にほとんど変更を必要としません。一方、特に応答オブジェクトでは、多くの場合、HTTPヘッダーを追加する必要があります。

さらに、不変性がPHPの世界で実際に使用されたことはありません。

不変の要求/応答オブジェクトを使用すると、どのような利点がありますか?


Jsonオブジェクトを返すとします。

$response = new JsonResponse($item);

素敵でシンプル。しかし、要求はクロスオリジンリソースシェアリング(CORS)要求であることがわかりました。応答を生成するコードは気にする必要はありませんが、下流のどこかに、必要なAccess-Controlヘッダーを追加するプロセスがあります。元の応答を維持し、追加のヘッダーを使用して新しい応答を作成する利点はありますか?それとも厳密にはプログラミングスタイルの問題です。

リクエストオブジェクトはもう少し興味深いです。同じように始まります:

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

初期情報を変更する必要はありません。ただし、要求が渡されると、処理情報を追加する必要が生じることがよくあります。たとえば、特定のリクエストに対して実行するアクションを決定するURLマッチャーがあるとします。

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

実際にアクションを実行するのは、下流プロセスの責任です。不変の要求をラップする変更可能なRequestAttributesCollectionを使用することもできますが、実際には少し扱いに​​くい傾向があります。また、属性コレクションを除いて、不変のリクエストを持つこともできます。例外も扱いにくい傾向があります。この種の要件に対処した経験はありますか?

10
Cerad

不変の要求/応答オブジェクトを使用すると、どのような利点がありますか?

@MainMaの声明に同意します「読みやすさのわずかな利点が柔軟性の欠如の可能性を補うかどうかはわかりません」と個人的にはわかりません強制の実用的で有用な側面PHP HTTP Request一時オブジェクトまたはPHP HTTP Response不変にする一時オブジェクト

この種の要件に対処した経験はありますか?

  1. MicrosoftのWindows Presentation Foundationフレームワークは freezableオブジェクト の概念を導入します。凍結すると、そのようなオブジェクトは

    • 不変(変更が試みられると例外をスローします)、
    • より高速に使用できます(プロパティゲッターは、もう "空想的な"私の価値は何か "の決定を行う必要がありません)。
    • 消費するメモリが少ない(内部ヘルパーのデータ構造やキャッシュなどを、時間とスペースの効率が最も高い表現に減らすことができます)
    • そして共有可能

    GUI速度の最適化として使用されますが、コンセプト自体はその利点を含め、他の場所にも適用できます

  2. Nancy( ".NetとMonoでHTTPベースのサービスを構築するための軽量で儀式の良いフレームワーク")は、不変の利点を コミットコメントの1つ として説明しています

    ...キャッシュがオフの場合、キャッシュは不変であると見なすことができます。つまり、ロックがないため、パフォーマンスが高速になります(ただし、ヒットはそれほど大きくありません)。

    不変性に関する他の注目すべきコメントは見つかりませんでしたが、再利用可能でキャッシュ可能な応答オブジェクトの利点はPHPにも適用される可能性があります

上記はトピック外の回答のように見えるかもしれませんが、私は他に何も知りません。そのため、不変性の要件は人為的な問題であり、むしろ好みやコーディングスタイルなどの問題だと思います。

4
xmojmr

不変オブジェクトには一般にいくつかの利点があります。

  • 最も重要なのは、並行して実行されるコードで不変オブジェクトをいかに簡単に使用できるかです。これは、なぜ "不変性がPHPの世界で実際に使われていないのか"も説明しています。

  • 状態の一貫性は簡単に取得できます。

  • オブジェクトは操作が簡単で、より自然です。

重要なことは、オブジェクトが存続期間中にどの程度変更する必要があるかです。不変オブジェクトを変更するたびに、追加のインスタンスを作成する必要があり、メモリ(およびおそらくCPUサイクル)の点ですぐにコストが高くなる可能性があります。これはまた、stringが不変であるほとんどのプログラミング言語が、C#のStringBuilderなどのある種の可変文字列用の別のクラスを作成し、多数の小さな文字列から文字列が連結される状況に対応するためです。パーツ、各パーツは動的に追加されます。

クライアント側のライブラリー(HTTP要求の送信と応答の受信)では、HTTP要求と応答を不変にするのが理にかなっています。一部の要求はFluentインターフェイスで構築できますが、これは主な使用法ではありません。とにかく応答は変更されないので、不変性は理にかなっています。

サーバー側のライブラリー(HTTP要求の受信と応答の送信)では、要求は不変である可能性がありますが、応答が可能かどうかはわかりません。データ自体はストリーム(一部の人にとっては、以下を参照)は応答オブジェクトを強制的に変更可能にすることができ、ヘッダー自体は、スクリプトの実行中に、応答が開始されるまで「オンザフライ」で追加できますクライアントに送信されます。

どちらの場合も、並列実行がないことを前提として、可読性のわずかな利点が柔軟性の欠如の可能性を補うかどうかはわかりません。

PSR-7に関するEvert Potによるより完全な記事 も必ずお読みください。この記事では、特に、そのような不変性が問題になるケースの1つよりも、ストリーミングする必要がある長い応答について説明しています。個人的には、私は要点を理解していません。IMHO、不変オブジェクトにストリームを含めることを禁止するものはありません(たとえば、FileReaderオブジェクトは、時間とともに変化する可能性のあるファイルを読み取っても、不変である可能性があります)。 PythonのFlaskフレームワークは 別のアプローチ を使用します。イテレータを返すことによって大きな応答(または生成に時間がかかる応答)になると).

7