Czy obiekty żądania / odpowiedzi HTTP powinny być niezmienne?

10

Myślę, że można bezpiecznie powiedzieć, że większość aplikacji internetowych opiera się na paradygmacie żądanie / odpowiedź. PHP nigdy nie miało formalnej abstrakcji tych obiektów. Jedna grupa próbuje to zmienić: https://github.com/php-fig/fig-standards/blob/master/proposed/http-message.md

W pewnym sensie udało im się jednak śledzić kwestię niezmienności. Z jednej strony obiekt zapytania / odpowiedzi zazwyczaj wymaga bardzo niewielkich zmian w trakcie swojego cyklu życia. Z drugiej strony, w szczególności obiekt odpowiedzi często wymaga dodania nagłówków HTTP.

Co więcej, niezmienność nigdy tak naprawdę nie przyjęła się w krainie PHP.

Jakie korzyści widzą ludzie, używając niezmiennych obiektów zapytania / odpowiedzi?


Załóżmy, że zwracasz obiekt Json.

$response = new JsonResponse($item);

Ładne i proste. Okazuje się jednak, że żądanie było żądaniem CORS (Cross-Origin Resource Sharing). Kod generujący odpowiedź nie powinien się przejmować, ale gdzieś poniżej znajduje się proces, który doda niezbędne nagłówki kontroli dostępu. Czy jest jakaś korzyść z zachowania oryginalnej odpowiedzi i utworzenia nowej z dodatkowymi nagłówkami? Czy jest to ściśle kwestia stylu programowania.

Obiekt żądania jest nieco bardziej interesujący. Zaczyna się tak samo:

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

Wstępnych informacji nie trzeba zmieniać. Ponieważ jednak żądanie zostaje przekazane, często konieczne jest dodanie dodatkowych informacji o przetwarzaniu. Na przykład możesz mieć dopasowujący adres URL, który decyduje o tym, jaka akcja powinna zostać wykonana dla danego żądania.

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

Właściwie wykonanie akcji jest obowiązkiem dalszego procesu. Możesz mieć zmienną RequestAttributesCollection, która otacza niezmienne żądanie, ale w praktyce jest to nieco niezręczne. Możesz również mieć żądanie, które jest niezmienne, z wyjątkiem kolekcji atrybutów. Wyjątki są również niewygodne. Jakieś doświadczenie w radzeniu sobie z tego rodzaju wymaganiami?

Cerad
źródło
Jeśli potrzebujesz tylko pierwotnej prośby / odpowiedzi, możemy zapisać klon obiektu, który zostanie ustawiony w c'torze, a następnie nie zostanie ponownie dotknięty. Możesz mutować, ale nadal uzyskać dostęp do oryginału, gdy zajdzie taka potrzeba. Prawdopodobnie byłoby to lepsze IMO.
mpen

Odpowiedzi:

4

Jakie korzyści widzą ludzie, używając niezmiennych obiektów zapytania / odpowiedzi?

Zgadzam się ze stwierdzeniem @ MainMa „ Nie jestem pewien, czy niewielka korzyść z czytelności rekompensuje możliwy brak elastyczności ” i osobiście nie widzę żadnych praktycznych i użytecznych aspektów zmuszania PHP HTTP Requestobiektów PHP HTTP Responsetymczasowych lub obiektów tymczasowych do niezmienności

Jakieś doświadczenie w radzeniu sobie z tego rodzaju wymaganiami?

  1. Windows Presentation FoundationStruktura Microsoft wprowadza koncepcję obiektów możliwych do zamrożenia . Po zamrożeniu takie przedmioty stają się

    • niezmienny (zgłaszaj wyjątki przy próbie modyfikacji),
    • szybsze w użyciu (osoby zajmujące się nieruchomościami nie muszą już podejmować żadnych wymyślnych decyzji „jaka jest moja wartość?”),
    • zużywa mniej pamięci (wewnętrzne struktury danych pomocniczych i pamięci podręczne itp. można zredukować do ich najbardziej wydajnej reprezentacji pod względem czasu i miejsca)
    • i możliwe do udostępnienia

    Chociaż jest on wykorzystywany jako optymalizacja prędkości GUI, sama koncepcja ma zastosowanie również w innych miejscach, w tym w jej zaletach

  2. Nancy(„Lekka, nisko-ceremonialna platforma do budowania usług opartych na HTTP na .Net i Mono”) opisuje zaletę niezmienności w jednym z komentarzy do zatwierdzenia jako

    ... możemy założyć, że nasze pamięci podręczne są niezmienne, jeśli są wyłączone, co oznacza, że ​​nie mamy blokad, więc szybsza wydajność (chociaż trafienie nie jest ogromne) ...

    Nie mogę znaleźć żadnych innych uwag godne uwagi o niezmienności, lecz korzyści z wielokrotnego użytku, Cacheable obiektów odpowiedź może dotyczyć PHPtakże

Powyższe może wyglądać jak odpowiedzi nie na temat, ale nie jestem świadomy niczego innego i dlatego uważam, że wymóg niezmienności jest sztucznym problemem, a raczej kwestią preferencji lub stylu kodowania itp.

xmojmr
źródło
1
Dzięki. Obie odpowiedzi miały charakter informacyjny. Postanowiłem zaakceptować twoje, ponieważ pojęcie zamrażania przedmiotów pomogło mi wyjaśnić moje myślenie. Zostaje utworzony niezmienny zamrożony obiekt odpowiedzi, ponieważ jakiś punkt tuż przed wysłaniem obiektu zostaje sklonowany i odmrożony. Można dodać paczki nagłówków zorientowanych na dostawę (skrzynki, korki itp.). Obiekt może następnie zostać zamrożony i wysłany po drodze.
Cerad,
7

Niezmienne obiekty mają ogólnie kilka zalet.

  • Najważniejsze z nich to to, jak łatwe jest używanie niezmiennych obiektów w kodzie wykonywanym równolegle. To tłumaczy także, dlaczego „niezmienność nigdy tak naprawdę nie przyjęła się w krainie PHP” .

  • Łatwiej jest uzyskać spójność stanu.

  • Przedmioty są łatwe w użyciu, bardziej naturalne.

Istotną rzeczą jest to, jak bardzo obiekt powinien się zmienić w ciągu swojego życia - każda zmiana na niezmienny obiekt wymaga stworzenia dodatkowej instancji, która może być szybko zbyt kosztowna pod względem pamięci (i prawdopodobnie również cykli procesora). Z tego też stringpowodu większość języków programowania, w których niezmienny jest końcowy, ma inną klasę dla pewnego rodzaju łańcuchów zmiennych, takich jak StringBuilderC #, aby reagować na sytuacje, w których łańcuchy są łączone z wielu małych części, a każda część jest dodawana dynamicznie.

W bibliotece po stronie klienta (wysyłanie żądania HTTP i odbieranie odpowiedzi) sensowne jest uczynienie żądania i odpowiedzi HTTP niezmiennymi: chociaż niektóre żądania mogą być budowane z płynnym interfejsem, nie jest to główne użycie. Odpowiedź i tak nie zostanie zmieniona, więc niezmienność ma sens.

W bibliotece po stronie serwera (odbieranie żądania HTTP i wysyłanie odpowiedzi), chociaż żądanie może być niezmienne, nie jestem pewien, czy odpowiedź może być. Same dane mogą być strumieniem (co dla niektórych osób - patrz poniżej - wymusza modyfikację obiektu odpowiedzi), a same nagłówki można dodawać „w locie” podczas wykonywania skryptu, dopóki odpowiedź nie zacznie zostać wysłanym do klienta.

W obu przypadkach, biorąc pod uwagę, że nie ma równoległego wykonywania, nie jestem pewien, czy niewielka korzyść z czytelności kompensuje możliwy brak elastyczności.

Przeczytaj także pełniejszy artykuł Evert Pot na temat PSR-7 . Artykuł wyjaśnia między innymi, że jednym z przypadków, w których taka niezmienność jest problematyczna, są długie odpowiedzi, które należy przesyłać strumieniowo . Osobiście nie widzę sensu: IMHO, nic nie zabrania niezmiennemu obiektowi zawierać strumienia (na przykład FileReaderobiekt może być niezmienny, nawet jeśli odczytuje plik, który może się zmieniać w czasie). Struktura Flask Pythona stosuje inne podejście, jeśli chodzi o duże odpowiedzi (lub odpowiedzi, których wygenerowanie wymaga czasu) poprzez zwrócenie iteratora.

Arseni Mourzenko
źródło
1
Jedną z zalet, o której warto również wspomnieć IMO, jest to, że gdy masz niezmienne obiekty, nigdy nie musisz zadawać sobie pytania, czy pracujesz z prywatną kopią, możesz dowolnie zmieniać lub referencje należące do innego obiektu, gdzie zmiany mogą wpływać na inne obiekty.
Philipp
@Philipp: IMHO, jednym z największych braków w Javie.NET jest brak konwencji umożliwiającej rozróżnienie między metodami, które zwracają odwołania do nowych obiektów, które może zmienić dowolna osoba wywołująca, a tymi, które zwracają odwołania, które są dołączone do lub hermetyzują wewnętrznie stan, który może być modyfikowany w celu manipulowania tym stanem oraz te, które zwracają odwołania do obiektu, który może lub może być dołączony do stanu wewnętrznego. Nie jest możliwe napisanie solidnego i wydajnego kodu bez wiedzy o tym, jakie rodzaje odniesień powinny zwrócić, ale nie ma konwencji, która by to wskazywała.
supercat
Dziękuję za odpowiedź. Prawie potwierdziło to, o czym myślałem, więc musi mieć rację. Postanowiłem zaakceptować odpowiedź xmoyxr, ponieważ podniósł koncepcję zamrażania obiektów, których wcześniej nie spotkałem.
Cerad,