[LARAVEL] 요청 & 응답

김세연·2025년 9월 24일

Laravel

목록 보기
14/14
post-thumbnail

요청(Request) & 응답(Response)

웹 애플리케이션의 동작은 레스토랑의 주문 과정과 정확히 일치한다.

  • 요청 (Request):
    손님이 웨이터에게 주문하는 행위이다. ("스테이크 하나, 미디움 레어로 주세요.")

  • 응답 (Response):
    주문을 받은 주방에서 요리가 나온 뒤, 웨이터가 손님에게 음식을 서빙하는 것이다.


요청 (Request): 손님의 '주문서'

요청(Request)은 사용자의 브라우저가 우리 서버로 보내는 모든 정보를 담은 '주문서'이다.
이 주문서에는 다음과 같은 정보가 담겨있다.

  • 무엇을 원하는가? (URI & Method):
    GET /tasks (할 일 목록을 '보여달라') 또는 POST /tasks (새 할 일을 '등록해달라')

  • 누가 주문했는가? (IP, Headers, Cookies):
    사용자의 IP 주소, 브라우저 정보, 로그인 정보(쿠키/토큰) 등

  • 특별 요청사항은? (Body/Payload):
    폼에 입력한 데이터(새 할 일의 제목 등)

라라벨에서의 요청: Illuminate\Http\Request 객체

라라벨은 이 모든 복잡한 요청 정보를 Request라는 하나의 편리한 객체로 깔끔하게 포장해서 컨트롤러에 전달해 준다.
이것이 바로 우리가 컨트롤러 메서드에서 의존성 주입으로 받아 사용하던 $request의 정체이다.

use Illuminate\Http\Request;

//            ↓ 라라벨이 모든 요청 정보를 담아 여기에 전달해 준다.
public function store(Request $request)
{
    // "주문서($request)에서 'title'이라는 항목의 값을 꺼내 줘."
    $title = $request->input('title');

    // "주문한 사람(로그인한 사용자)의 정보를 알려 줘."
    $user = $request->user();

    // "주문서의 내용이 유효한지(예: title이 비어있지 않은지) 검사해 줘."
    $validated = $request->validate(['title' => 'required']);
    
    // ...
}

2. 응답 (Response): 주방장의 '요리'

응답(Response)은 컨트롤러에서의 모든 처리가 끝난 후, 서버가 사용자의 브라우저로 다시 보내주는 '결과물'이다.
여기에는 다음과 같은 정보가 포함된다.

  • 핵심 내용 (Body):
    실제 보여줄 데이터 (HTML 코드, JSON 데이터 등)

  • 주문 처리 결과 (Status Code):
    주문이 성공했는지, 실패했는지 등을 알려주는 숫자 코드 (예: 200 OK, 404 Not Found, 500 Server Error)

  • 내용물에 대한 정보 (Headers):
    "이 내용은 HTML입니다"(Content-Type: text/html) 또는 "JSON 데이터입니다"(Content-Type: application/json) 같은 부가 정보

라라벨에서의 응답: response() 헬퍼

컨트롤러 메서드의 return 값은 모두 최종적으로 응답(Response) 객체로 변환되어 사용자에게 보내진다.
라라벨은 response() 헬퍼 함수를 통해 다양한 형태의 응답을 매우 쉽게 만들 수 있도록 지원합니다.

// 1. Eloquent 모델이나 컬렉션을 반환하는 경우
public function index()
{
    // 라라벨이 알아서 JSON 형태로 변환하고, 상태 코드 200(OK)을 보낸다.
    return Task::all();
}

// 2. JSON 응답을 직접 만드는 경우 (가장 일반적인 API 방식)
public function store(Request $request)
{
    $task = Task::create($request->validated());

    // '201 Created' 상태 코드와 함께 생성된 데이터를 JSON으로 반환한다.
    return response()->json($task, 201);
}

// 3. 웹 페이지(뷰)를 반환하는 경우
public function create()
{
    return view('tasks.create'); // resources/views/tasks/create.blade.php 파일을 렌더링
}

// 4. 다른 주소로 이동시키는 경우 (리다이렉트)
public function someAction()
{
    return redirect('/home');
}

요청 (Request) 심화

다양한 입력값 조회 방법

$request->input('key')은 대부분의 상황에서 통하지만, 요청의 종류에 따라 더 명확한 메서드를 사용할 수 있다.

  • $request->query('key'):
    URL의 쿼리 문자열(Query String)에서만 값을 가져온다.
    (예: /users?page=2 에서 page 값을 가져올 때)

  • $request->post('key'):
    POST, PUT, PATCH 요청의 Body에서만 값을 가져온다.

  • $request->title (동적 속성):
    input() 메서드보다 짧게 입력값을 조회할 수 있는 방식이다.

  • $request->all():
    모든 입력값을 배열로 가져온다.

  • $request->only([...]) / $request->except([...]):
    원하는 키의 값만 선택하거나, 특정 키의 값만 제외하고 가져올 때 유용하다.

파일 처리 (File Uploads)

사용자가 이미지를 포함한 폼을 제출했을 때, 파일은 일반적인 입력값과는 다르게 처리된다.

public function store(Request $request)
{
    // 'profile_image' 라는 이름의 파일이 있는지 확인
    if ($request->hasFile('profile_image')) {

        // 파일 유효성 검사
        $request->validate(['profile_image' => 'required|image|max:2048']);

        // 파일을 'public/images' 폴더에 저장하고, 저장된 경로를 반환
        $path = $request->file('profile_image')->store('images', 'public');

        // ... 데이터베이스에 경로 저장
    }
}

$request->file() 메서드를 통해 업로드된 파일에 접근하고, store() 메서드로 간단하게 파일을 저장할 수 있다.

요청 생명주기 (Request Lifecycle)

Request 객체는 컨트롤러에서 처음 만들어지는 것이 아니라, 라라벨 애플리케이션이 시작되는 가장 첫 순간에 생성된다.
그리고 우리가 배운 라우터와 여러 미들웨어를 차례대로 통과하면서 컨트롤러에 최종적으로 도착하게 된다.
이 흐름을 이해하면 미들웨어에서 요청을 어떻게 조작하거나 검사하는지 더 깊이 있게 파악할 수 있다.


응답 (Response) 심화

1. 응답 매크로 (Response Macros) - 나만의 응답 만들기

애플리케이션 전체에서 반복적으로 사용되는 특정 응답 형식이 있다면, 매크로(Macro)를 통해 나만의 커스텀 응답 메서드를 만들 수 있다.

  • 정의하기 (AppServiceProvider.php):
    boot() 메서드 안에 매크로를 정의한다.
    예를 들어, 표준화된 에러 응답 형식을 만들어 보면
use Illuminate\Support\Facades\Response;

public function boot()
{
    Response::macro('error', function ($message, $statusCode = 400) {
        return Response::json([
            'success' => false,
            'message' => $message,
        ], $statusCode);
    });
}
  • 사용하기 (컨트롤러에서):
    이제 어디서든 response()->error() 라는 나만의 메서드를 사용할 수 있다.
public function show($id)
{
    $task = Task::find($id);
    if (!$task) {
        return response()->error('해당 작업을 찾을 수 없습니다.', 404);
    }
    // ...
}

헤더와 쿠키 추가하기

응답에는 Body(내용)뿐만 아니라, 추가적인 정보를 담은 헤더(Header)나 쿠키(Cookie)를 함께 보낼 수 있다.

return response()->json($data)
    ->header('X-Custom-Header', 'SomeValue') // 커스텀 헤더 추가
    ->cookie('my_cookie', 'cookie_value', 60); // 60분 동안 유효한 쿠키 추가

API 리소스 (API Resources) - 최고의 응답 방식

이전에 컨트롤러 파트에서 배운 API 리소스는 최고의 JSON 응답 생성 방식이다.
API 응답의 형식을 중앙에서 관리하고, 모델 데이터를 원하는 대로 가공하며, 관계 데이터까지 쉽게 포함시킬 수 있다.
단순히 response()->json()을 사용하는 것보다 훨씬 더 구조적이고 유지보수가 용이한 방법이므로, 전문적인 API를 만들 때는 항상 API 리소스를 사용하는 것이 좋다.


결론

요청(Request)과 응답(Response)은 웹 애플리케이션이라는 세상의 기본적인 소통 언어이자, 모든 상호작용의 시작과 끝이다.

profile
공부 재밌따

0개의 댓글