제5.5장: 웹 페이지 라우팅
학습 시간: 40분
1. routes/web.php
vs routes/api.php
: 두 가지 다른 제어판
근본적인 차이를 다시 한번 확실히 해두는 것이 중요합니다:
특성 | routes/web.php (웹 제어판) |
routes/api.php (API 제어판) |
---|---|---|
주요 목적 | HTML 페이지 표시, 폼 처리 | 다른 애플리케이션을 위한 JSON 형식 데이터 제공 |
상태 (State) | Stateful (상태 유지) — 세션 및 쿠키 사용 | Stateless (무상태) — 각 요청 독립적 |
기본 미들웨어 | web (세션, CSRF 보호, 쿠키 암호화 포함) |
api ("스로틀링" — 요청 빈도 제한 포함) |
URL 접두사 | 없음 (사이트의 루트) | /api/ (RouteServiceProvider 에서 설정) |
인증 | 일반적으로 세션 사용 (로그인/비밀번호) | 일반적으로 토큰 사용 (Sanctum, Passport) |
우리는 실제 사용자를 위한 인터페이스를 구축하기 위해 routes/web.php
를 사용합니다.
2. 웹용 리소스 라우트
Route::apiResource
와 유사하게, 웹을 위한 Route::resource
가 존재합니다. 이것은 생성 및 편집 폼을 표시하는 페이지를 포함하여 전체 CRUD 사이클을 위한 라우트를 생성합니다.
웹 인터페이스를 통해 행성을 관리하기 위한 전체 라우트 세트를 만들어 봅시다.
1단계: routes/web.php
에 라우트 생성
기존의 /planets
라우트를 주석 처리하거나 삭제하고 한 줄로 대체합니다:
use App\Http\Controllers\Web\PlanetPageController;
// Route::get('/planets', [PlanetPageController::class, 'index']);
// Route::get('/planets/{planet}', [PlanetPageController::class, 'show']);
Route::resource('planets', PlanetPageController::class);
2단계: 생성된 내용 확인
터미널에서 php artisan route:list --except-vendor
명령을 실행합니다:
+--------+-----------+------------------------+------------------+-------------------------------------------------+------------+
| Method | URI | Name | Action | Middleware |
+--------+-----------+------------------------+------------------+-------------------------------------------------+------------+
| GET|HEAD | planets | planets.index | ...\PlanetPageController@index | web |
| POST | planets | planets.store | ...\PlanetPageController@store | web |
| GET|HEAD | planets/create | planets.create | ...\PlanetPageController@create | web |
| GET|HEAD | planets/{planet} | planets.show | ...\PlanetPageController@show | web |
| PUT|PATCH | planets/{planet} | planets.update | ...\PlanetPageController@update | web |
| DELETE | planets/{planet} | planets.destroy | ...\PlanetPageController@destroy | web |
| GET|HEAD | planets/{planet}/edit | planets.edit | ...\PlanetPageController@edit | web |
+--------+-----------+------------------------+------------------+-------------------------------------------------+------------+
Route::resource
는 다음을 포함하여 7개의 라우트를 생성했습니다:
planets.create
(GET/planets/create
): 생성 폼이 있는 페이지.planets.store
(POST/planets
): 이 폼 처리.planets.edit
(GET/planets/{planet}/edit
): 편집 폼이 있는 페이지.planets.update
(PUT/PATCH/planets/{planet}
): 편집 폼 처리.planets.destroy
(DELETE/planets/{planet}
): 리소스 삭제.
3. 명명된 라우트: 편리한 "우주 좌표"
Name
열에 주목하세요. Laravel은 각 라우트에 고유한 이름(예: planets.index
)을 자동으로 할당했습니다. 하드코딩된 URL 대신 이름을 사용하는 것이 가장 좋은 방법입니다.
왜 그럴까요? URL을 /planets
에서 /worlds
로 변경하기로 결정하더라도, 템플릿의 모든 링크를 찾아 변경할 필요가 없습니다. 라우트 파일의 한 곳에서만 변경하면 되며, 이름은 그대로 유지됩니다.
Blade에서 사용 예시:
이전에는 다음과 같이 작성했습니다:
이제 route()
헬퍼를 사용하여 다음과 같이 작성할 것입니다:
route('planets.show', ...)
—planets.show
라는 이름의 라우트에 대한 URL을 생성합니다.['planet' => $planet->id]
— 필요한 매개변수를 URL에 전달합니다. Laravel은{planet}
에 ID를 자동으로 채워넣습니다. 모델 전체를 전달할 수도 있습니다:['planet' => $planet]
.
4. 컨트롤러에 누락된 메서드 구현
Route::resource
는 라우트를 생성했지만, PlanetPageController
에 해당하는 메서드는 우리가 직접 생성해야 합니다.
app/Http/Controllers/Web/PlanetPageController.php
를 열고 추가해 봅시다.
<?php
use Illuminate\Http\Request; // <-- 추가
class PlanetPageController extends Controller
{
// index()와 show()는 이미 있습니다
/**
* 새 행성을 생성하기 위한 폼을 표시합니다.
*/
public function create()
{
return view('planets.create'); // 단순히 폼이 있는 뷰를 반환합니다
}
/**
* 새 행성을 데이터베이스에 저장합니다.
*/
public function store(Request $request)
{
// 폼 데이터 유효성 검사
$validated = $request->validate([
'name' => 'required|string|max:255|unique:planets',
'solar_system' => 'required|string|max:100',
// ... 기타 규칙
]);
Planet::create($validated);
// 사용자에게 성공 메시지와 함께 목록 페이지로 리디렉션합니다
return redirect()->route('planets.index')->with('success', '행성이 성공적으로 생성되었습니다!');
}
/**
* 행성 편집 폼을 표시합니다.
*/
public function edit(Planet $planet)
{
return view('planets.edit', ['planet' => $planet]);
}
/**
* 데이터베이스에서 행성 데이터를 업데이트합니다.
*/
public function update(Request $request, Planet $planet)
{
$validated = $request->validate([
'name' => 'required|string|max:255|unique:planets,name,' . $planet->id,
'solar_system' => 'required|string|max:100',
]);
$planet->update($validated);
return redirect()->route('planets.show', $planet)->with('success', '행성 데이터가 업데이트되었습니다!');
}
/**
* 행성을 삭제합니다.
*/
public function destroy(Planet $planet)
{
$planet->delete();
return redirect()->route('planets.index')->with('success', '행성이 폐기되었습니다.');
}
}
redirect()->route(...)
— 사용자를 다른 명명된 라우트로 리디렉션합니다.->with('success', '...')
— 세션에 "플래시 메시지"를 추가하며, 이 메시지는 다음 페이지에서 정확히 한 번만 사용할 수 있습니다. 이 메시지를 Blade 템플릿에 표시할 수 있습니다.
5. 라우트 그룹화
공통 특성을 가진 많은 라우트(예: 모두 관리자 패널용이며 /admin
접두사와 특별한 미들웨어를 가져야 함)가 있다면, 이들을 그룹화할 수 있습니다.
<?php
Route::middleware(['auth', 'admin'])->prefix('admin')->name('admin.')->group(function () {
// 이 그룹 내의 모든 라우트는 다음을 가집니다:
// 1. 'auth' 및 'admin' 미들웨어
// 2. URL 접두사 '/admin' (예: /admin/planets)
// 3. 이름 접두사 'admin.' (예: admin.planets.index)
Route::resource('planets', PlanetPageController::class);
// Route::get('/dashboard', ...)->name('dashboard'); // -> admin.dashboard
});
복습 퀴즈
🚀 챕터 요약:
Laravel에서 웹 경로를 구성하는 구조화되고 전문적인 접근 방식을 마스터했습니다. 이제 다음을 할 수 있습니다:
web
및api
경로와 그 목적을 구별합니다.Route::resource
를 사용하여 표준 CRUD 경로를 빠르게 생성합니다.- 유연하고 유지보수 가능한 코드를 생성하기 위해 명명된 경로를 사용합니다.
- 유효성 검사 및 리디렉션을 통해 컨트롤러에서 완전한 CRUD 작업을 생성합니다.
- 공통 규칙을 적용하기 위해 경로를 그룹화합니다.
이제 당신의 "함선"의 내비게이션 시스템은 오류 허용적이며 확장을 위한 준비가 되었습니다. 이 섹션의 마지막 챕터에서는 지금까지 얻은 모든 지식을 통합하여 Fetch를 통해 얻은 행성 데이터를 우리의 Blade 페이지에 표시할 것입니다.