라라벨의 HTTP Response 는 처리한 결과를 웹 브라우저에게 전송하는 역할을 수행하는 클래스입니다.

 

라라벨의 HTTP Request/Response 클래스는 심포니(Symphony) 프레임워크의 HTTP Request 와 HTTP Response 클래스를 상속하여 사용하고 있습니다.

심포니 프레임워크는 PSR 표준을 따르는 프레임워크이므로 다른 프레임워크와 상호 연계가 가능하며 개발자가 취향대로 다른 프레임워크의 기능을 사용할 수 있습니다.

 

브라우저가 요청을 전송한 방식(HTTP 의 Content-Type 헤더나 Accept 헤더등) 이나 서버가 전송하는 컨텐츠의 종류에 따라 Response 는 여러 가지 유형이 있을 수 있습니다.

 

전 절에서 작성한 예제 코드를 보면 특별한 Reponse 를 지정하지 않고 Route::get 에 설정한 클로저에서 문자열을 리턴했습니다.

이 경우 기본 Response 가 생성되며 서버가 전송하는 Content-Type: 헤더는 text/html 이 지정됩니다. 전 장에서 설명한 HTTP 디버깅 툴인 피들러를 통해서 오가는 HTTP 데이타를 살펴 보겠습니다.

 

HTTP/1.1 200 OK
Server: nginx/1.6.2
Content-Type: text/html; charset=UTF-8 -------- (1)
Transfer-Encoding: chunked
Connection: keep-alive
Cache-Control: no-cache
Date: Sat, 06 Jun 2015 14:12:56 GMT
Set-Cookie: XSRF-TOKEN=eyJpdiI...;expires=Sat, 06-Jun-2015 16:12:56 GMT; Max-Age=7200; path=/ ---------------------(2)
Set-Cookie: laravel_session=eyJpdiI.;expires=Sat, 06-Jun-2015 16:12:56 GMT; Max-Age=7200; path=/; httponly  ---------------------(3)

Hello World name -------------------------- (4)

(1) 번을 보면 라라벨의 기본 Response 가 동작하여 Content-Type: 을 text/html 로 문자열 인코딩은 UTF-8 로 설정해서 보내는 것을 알 수 있습니다. 

다음 (2), (3) 번은 라라벨이 자동으로 삽입하는 헤더이며 라라벨의 특징에서 설명한 "크로스 사이트 요청 위조"(CSRF)를 막기 위한 헤더로 나중에 미들웨어 항목에서 설명할 것입니다. 

 

마지막 (4) 은 서버가 보낸 실제 컨텐츠입니다. 보통 gzip 으로 컨텐츠를 압축할 경우가 많고 이때 Content-Encoding: gzip 헤더가 추가 됩니다.

Content-Type: 헤더는 text/html 로 보냈지만 HTML 태그가 없는 문자열이 전송되었음을 알 수 있습니다.

 

태그가 없는 문자열이므로 Content-Type:  text/plain 으로 설정하는게 더 정확하므로 라라벨의 Response 클래스를 사용하여 헤더를 수정해 보겠습니다.

routes.php

<?php
 
use Illuminate\Http\Response;

Route::get('hello/world/{name}', function($name) {
	$response = new Response('Hello World ' . $name, 200);
	$response->header('Content-Type', 'text/plain');
	return $response;
});
CODE
Response 클래스는 다른 네임 스페이스에 있으므로 use Illuminate\Http\Response; 구문을 추가해야 합니다

 

이제 피들러로 서버의 응답을 확인해 보면 Content-type: text/plain 으로 변경되었음을 알수 있습니다.

 

Response 객체를 사용하기 위해 use 구문을 선언하고 new 로 객체를 생성하는 것은 번거롭습니다.

라라벨은 response 라는 헬퍼 클래스를 제공하고 있으므로 이것을 사용하면 use 와 new 구문을 쓰지 않고도 response 를 사용할 수 있습니다.

routes.php

<?php 

Route::get('hello/world/{name}', function($name) {
	return response('Hello World ' . $name, 200)->header('Content-Type', 'text/plain');
});
CODE

 

Response 로 HTTP 헤더를 다룰 수 있으므로 다른 헤더도 설정해 보겠습니다. 캐쉬 정책을 설정하는 헤더인 Cache-Control: 은 라라벨은 이미지나 .css, .js 같은 정적 컨텐츠가 아닐 경우 기본 값으로 no-cache 로 설정합니다. 

캐쉬를 최대 1시간으로 설정해 보겠습니다. 캐쉬의 유효 기간을 설정하는 max-age 값은 초단위이므로 1시간일 경우 60 * 60 이므로 3,600 을 설정하면 됩니다.

 

<?php

Route::get('hello/world/{name}', function($name) {
	return response('Hello World ' . $name, 200)
				->header('Content-Type', 'text/plain')
				->header('Cache-Control', 'max-age=' . 60*60 . ", must-revalidate");
});
CODE

위 코드는 Cache-Control : max-age : 3600, must-revalidate 헤더를 설정하며 3600 초 동안 서버에 재 요청하지 않고 컨텐츠를 재사용하며 3600 초가 지나면 캐쉬를 재검증해야 한다는 의미입니다.

 

빌더 패턴

-> 를 구분자로 하여 동시에 메소드를 여러 번 호출하는 것을 메소드 체이닝(Method Chaining) 이라 하며 이를 지원하는 디자인 패턴을 Fluent Interface 라고 부릅니다.

메소드 체이닝을 지원하도록 하려면 호출하는 메소드에서 $this 객체를 리턴하면 됩니다.

이제 브라우저로 다시 연결한 후에 피들러로 HTTP 헤더를 살펴보면 다음과 같이 Cache-Control 헤더가 변경되어 있음을 확인할 수 있습니다.

 

 

최근의 웹 개발에서 많이 사용하는 데이타 형식은 JSON 입니다. 라라벨의 Response 클래스는 PHP 배열을 손쉽게 json 으로 변환하여 클라이언트에 전송할 수 있는 기능이 있습니다.

<?php
 
Route::get('hello/json', function() {
	$data = ['name' => 'Iron Man', 'gender' => 'Man'];
	
	return response()->json($data);
}); 
CODE

 

웹 브라우저로 연결해 보면 다음과 같이 json 형식의 응답이 오는 것을 확인할 수 있습니다.