Skip to content

2.4장: PlanetController API 컨트롤러

학습 시간: 1시간


1. 컨트롤러: 우주 객체 관리 센터

MVC 아키텍처에서 컨트롤러는 모델과 요청 사이의 중개자입니다:

  • 📡 HTTP 요청(GET, POST, PUT, DELETE) 수신
  • 🔍 모델을 통해 데이터베이스에서 데이터 추출
  • 📦 API를 위한 JSON 응답 생성

💡 우주 비유: PlanetController = 미션 통제 센터(MCC):

  • 지구로부터 요청 수신 (GET /planets)
  • "탐사선"(모델)에 명령 전달
  • JSON 형식으로 원격 측정 데이터 반환

2. 리소스 컨트롤러 생성

리소스 컨트롤러는 CRUD 작업을 위한 메서드를 자동으로 포함합니다.

1단계: 컨트롤러 생성

php artisan make:controller PlanetController --api --model=Planet

app/Http/Controllers/PlanetController.php에 생성될 내용:

<?php

namespace App\Http\Controllers;

use App\Models\Planet;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule; // 이 임포트를 추가하는 것을 잊지 마세요.

class PlanetController extends Controller
{
    // 행성 목록 표시
    public function index(Request $request) {}

    // 새로운 행성 생성
    public function store(Request $request) {}

    // 특정 행성 표시
    public function show(Planet $planet) {}

    // 행성 업데이트
    public function update(Request $request, Planet $planet) {}

    // 행성 삭제
    public function destroy(Planet $planet) {}
}


3. API 메서드 구현

A. index() - 행성 목록 가져오기

<?php
public function index(Request $request)
{
    // 페이지당 15개씩, 페이지네이션된 행성 가져오기
    $planets = Planet::paginate($request->get('per_page', 15));
    return response()->json($planets); // 자동 200 OK
}

B. store() - 새로운 행성 생성

<?php
public function store(Request $request)
{
    $data = $request->validate([
        'name' => 'required|string|max:255|unique:planets',
        'description' => 'required|string',
        'size_km' => 'required|integer|min:100',
        'solar_system' => 'required|string|max:100',
        'image_url' => 'nullable|url',
        'is_habitable' => 'boolean'
    ]);

    $planet = Planet::create($data);
    return response()->json($planet, 201); // 201 Created
}

C. show() - 단일 행성 보기

<?php
public function show(Planet $planet)
{
    return response()->json($planet); // 자동 200 OK
}

D. update() - 행성 업데이트

<?php
public function update(Request $request, Planet $planet)
{
    $data = $request->validate([
        'name' => [
            'string',
            'max:255',
            Rule::unique('planets')->ignore($planet->id),
        ],
        'description' => 'sometimes|string', // 'sometimes' - 필드가 전송된 경우에만 유효성 검사
        'size_km' => 'sometimes|integer|min:100',
        'solar_system' => 'sometimes|string|max:100',
        'image_url' => 'sometimes|nullable|url',
        'is_habitable' => 'sometimes|boolean'
    ]);

    $planet->update($data);
    return response()->json($planet); // 200 OK
}

E. destroy() - 행성 삭제

<?php
public function destroy(Planet $planet)
{
    $planet->delete();
    return response()->json(null, 204); // 204 No Content
}


4. 라우트 모델 바인딩 (Route Model Binding)

Laravel은 ID에 따라 행성 객체를 자동으로 삽입합니다:

// 라우트: GET /planets/{planet}
// 메서드: show(Planet $planet)

  • 행성을 찾을 수 없는 경우 → 자동 404
  • findOrFail()을 사용하여 수동으로 쿼리할 필요 없음

5. 응답 형식 지정

index()에 대한 개선된 응답 예시:

<?php
public function index()
{
    return response()->json([
        'success' => true,
        'data' => Planet::all(),
        'message' => '행성을 성공적으로 가져왔습니다'
    ]);
}

404 오류 시 응답 (자동):

{
    "message": "No query results for model [App\\Models\\Planet] 123",
    "exception": "Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException"
}


복습 퀴즈

1. API 컨트롤러를 생성하는 플래그:

2. 성공적인 생성 시 어떤 상태를 반환해야 합니까?

3. 라우트 모델 바인딩은 다음을 허용합니다:

4. 행성 삭제 시 반환하는 것은:

5. `$request->validate()`는 다음 용도로 사용됩니다:


🚀 이 장의 요약:

이제 행성 시스템의 "제어판"을 만들었습니다! 이제 컨트롤러는 다음을 수행할 수 있습니다:

  • 🌌 행성 목록 표시 (index)
  • 🪐 새로운 행성 생성 (store)
  • 🔭 행성 데이터 상세 표시 (show)
  • 🛠️ 정보 업데이트 (update)
  • 💥 행성 삭제 (destroy)

이제 경로를 설정해야 합니다! 다음 장에서는 컨트롤러를 API 경로에 연결할 것입니다.

📌 확인:

app/Http/Controllers에 5개의 메서드가 있는 PlanetController.php가 있는지 확인하세요.

⚠️ 오류 발생 시:

  • 모델 이름 확인: use App\Models\Planet;
  • 임포트 확인
  • PostgreSQL의 경우: Planet::all()이 데이터를 반환하는지 확인하세요.
  • Tinker 문제 발생 시: composer dump-autoload를 실행하세요.