HTTP 요청 / 응답 객체를 변경할 수 없습니까?


10

대부분의 웹 응용 프로그램은 요청 / 응답 패러다임을 기반으로하는 것이 안전하다고 생각합니다. PHP는 이러한 객체를 공식적으로 추상화 한 적이 없습니다. 한 그룹이 이것을 변경하려고합니다 : https://github.com/php-fig/fig-standards/blob/master/proposed/http-message.md

그러나 그들은 불변성 문제에 대해 부수적으로 추적했습니다. 한편으로 요청 / 응답 객체는 일반적으로 수명주기 동안 거의 변경이 필요하지 않습니다. 반면에 응답 객체는 특히 HTTP 헤더를 추가해야하는 경우가 종종 있습니다.

더욱이, 불변성은 PHP의 땅에서 실제로 잡히지 않았습니다.

불변의 요청 / 응답 객체를 사용할 때 사람들이 얻는 이점


json 객체를 반환한다고 가정 해 봅시다.

$response = new JsonResponse($item);

좋고 간단합니다. 그러나 요청은 CORS (Cross-Origin Resource Sharing) 요청이었습니다. 응답을 생성하는 코드는 신경 쓰지 말고 다운 스트림 어딘가는 필요한 Access-Control 헤더를 추가하는 프로세스입니다. 원래 응답을 유지하고 추가 헤더로 새 응답을 작성하면 어떤 이점이 있습니까? 아니면 프로그래밍 스타일의 문제입니까?

요청 객체는 좀 더 흥미 롭습니다. 동일하게 시작됩니다.

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

초기 정보는 변경할 필요가 없습니다. 그러나 요청이 전달됨에 따라 추가 처리 정보를 추가해야하는 경우가 종종 있습니다. 예를 들어, 주어진 요청에 대해 어떤 조치를 수행해야하는지 결정하는 URL 매 처가있을 수 있습니다.

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

실제로 작업을 실행하는 것은 다운 스트림 프로세스의 책임입니다. 불변의 요청을 감싸는 변경 가능한 RequestAttributesCollection을 가질 수 있지만 실제로는 다소 어색합니다. 속성 콜렉션을 제외하고는 불변의 요청을 가질 수도 있습니다. 예외도 어색한 경향이 있습니다. 이러한 종류의 요구 사항을 처리 한 경험이 있습니까?


필요한 원래 요청 / 응답 일 경우 c'tor에서 설정 한 개체의 복제본을 저장할 수 있으며 다시는 만지지 않습니다. 필요할 때마다 음소거 할 수 있지만 여전히 원본에 액세스 할 수 있습니다. 이것은 아마도 더 나은 IMO 일 것입니다.
mpen

답변:


4

불변의 요청 / 응답 객체를 사용할 때 사람들이 얻는 이점

MainMa의 문 @에 동의 " 난 확실하지 가독성의 약간의 이점은 유연성의 결여를 보상하는 경우 "개인적으로 나는 강제의 실용적이고 유용한 측면이 표시되지 않는 PHP HTTP Request임시 개체 또는 PHP HTTP Response불변 임시 객체를

이러한 종류의 요구 사항을 처리 한 경험이 있습니까?

  1. Microsoft의 Windows Presentation Foundation프레임 워크에는 고정 가능한 개체의 개념이 도입되었습니다 . 냉동되면 이러한 물체는

    • 불변 (수정 시도시 예외 발생),
    • 더 빠르게 사용 (속성 게터는 더 이상 "내 가치가 무엇입니까?"결정을 내릴 필요가 없음),
    • 적은 메모리 소비 (내부 헬퍼 데이터 구조 및 캐시 등을 시간 및 공간 효율적인 표현으로 줄일 수 있음)
    • 공유 가능

    GUI 속도 최적화로 사용되지만 개념 자체는 이점을 포함하여 다른 곳에서도 적용 가능합니다.

  2. Nancy( ".Net 및 Mono에서 HTTP 기반 서비스를 구축하기위한 경량의 낮은 식의 프레임 워크") 는 커밋 주석 중 하나 에서 불변성의 이점을 다음과 같이 설명 합니다.

    ... 캐시가 꺼져 있으면 캐시를 변경할 수 없다고 가정 할 수 있습니다. 즉, 잠금이 없으므로 성능이 더 빠릅니다 (적중이 크지는 않지만) ...

    불변성에 대한 다른 주목할만한 의견을 찾지 못했지만 재사용 가능하고 캐시 가능한 응답 객체의 이점도 적용될 수 PHP있습니다.

위의 주제는 주제를 벗어난 답변처럼 보이지만 다른 것을 알지 못하므로 불변성 요구 사항이 인위적인 문제이며 선호도 또는 코딩 스타일 등의 문제라고 생각합니다.


1
감사. 두 답변 모두 유익했습니다. 나는 얼어 붙은 물건이라는 개념이 내 생각을 분명히하는 데 도움이 되었기 때문에 당신을 받아들이기로 결정했습니다. 객체를 보내기 직전의 시점이 복제되고 고정 해제되기 때문에 불변의 고정 된 응답 객체가 생성됩니다. 전달 지향 헤더 (캐시, cors 등)를 추가 할 수 있습니다. 그런 다음 개체를 고정하여 그대로 보낼 수 있습니다.
Cerad

7

불변 개체는 일반적으로 몇 가지 이점이 있습니다.

  • 가장 중요한 것은 병렬로 실행되는 코드에서 불변 객체를 사용하는 것이 얼마나 쉬운 지입니다. 이것은 왜 "불변성이 PHP 영역에서 실제로 잡히지 않았는가 "를 설명합니다 .

  • 상태 일관성을 쉽게 얻을 수 있습니다.

  • 개체는 작업하기 쉽고 자연 스럽습니다.

중요한 것은 수명 동안 객체가 얼마나 많이 변경되어야 하는가입니다. 불변의 객체로 변경할 때마다 추가 인스턴스를 생성해야하므로 메모리 측면에서 너무 비싸고 CPU 주기도 빠를 수 있습니다. 이것은 또한 string불변 인 대부분의 프로그래밍 언어 가 StringBuilder문자열이 많은 작은 부분에서 연결되어 각 부분이 동적으로 추가되는 상황에 응답하기 위해 C # 과 같은 일종의 가변 문자열에 대한 다른 클래스를 갖도록 하는 이유 입니다 .

클라이언트 측 라이브러리 (HTTP 요청 전송 및 응답 수신)에서는 HTTP 요청 및 응답을 변경 불가능하게 만드는 것이 합리적입니다. 일부 요청은 유동적 인 인터페이스로 빌드 될 수 있지만 이는 주요 사용법이 아닙니다. 응답은 어쨌든 변경되지 않으므로 불변성은 의미가 있습니다.

서버 측 라이브러리 (HTTP 요청 수신 및 응답 전송)에서 요청을 변경할 수 없지만 응답이 가능한지 확실하지 않습니다. 데이터 자체는 스트림 일 수 있으며 (아래 참조) 응답 객체를 변경 가능하게하고 스크립트가 실행되는 동안 응답이 시작될 때까지 헤더 자체를 "즉시"추가 할 수 있습니다. 클라이언트에게 보내집니다.

두 경우 모두 병렬로 실행이 없다면 가독성의 약간의 이점이 가능한 유연성 부족을 보상하는지 확실하지 않습니다.

PSR-7에 대한 Evert Pot더 완전한 기사 도 읽으십시오 . 이 기사는 무엇 보다도 이러한 불변성이 문제가되는 경우 중 하나 이상이 긴 응답을 위해 스트리밍되어야한다는 것을 설명 합니다. 개인적으로, 나는 요점을 보지 못한다 : IMHO, 불변의 객체가 스트림을 포함하는 것을 금지하는 것은 없다 (예를 들어, FileReader시간이 지남에 따라 변할 수있는 파일을 읽는 경우에도 객체는 불변 일 수 있음). Python의 Flask 프레임 워크는 반복자를 반환하여 큰 응답 (또는 생성하는 데 시간이 걸리는 응답)에 대해서는 다른 접근 방식을 사용 합니다.


1
IMO를 언급 할 가치가있는 한 가지 장점은 변경 불가능한 객체가있는 경우 개인 사본으로 작업 중인지 자신에게 묻지 않아도 자유롭게 변경하거나 다른 객체가 소유 한 참조를 자유롭게 변경할 수 있으며 다른 객체에 영향을 줄 수 있다는 것입니다.
Philipp

@Philipp : Java.NET의 가장 큰 결함 중 하나 인 IMHO는 호출자가 마음대로 변경할 수있는 새 객체에 대한 참조를 반환하는 메서드와 내부에 첨부되거나 캡슐화 된 참조를 반환하는 메서드를 구별하는 규칙이 부족하다는 것입니다. 상태를 조작하기 위해 수정 될 수있는 상태 및 내부 상태에 연결되거나 첨부 될 수있는 객체에 대한 참조를 반환하는 상태. 어떤 종류의 참조가 반환되어야하는지 알지 못하면 강력하고 효율적인 코드를 작성할 수는 없지만이를 나타내는 규칙은 없습니다.
supercat

답변 해주셔서 감사합니다. 그것은 내가 생각했던 것을 거의 확인했기 때문에 그것이 옳 아야합니다. 나는 xmoyxr의 대답을 수락하기로 결정했습니다.
Cerad
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.