2.6장: 데이터 유효성 검사
학습 시간: 50분
1. 유효성 검사: 우주 규모의 방패
유효성 검사(Validation)는 들어오는 데이터가 규칙을 준수하는지 확인하는 것입니다. 유효성 검사 없이는:
- 🚀 잘못된 데이터가 데이터베이스를 "파괴"할 수 있습니다
- 🌌 악의적인 사용자가 악성 코드를 주입할 수 있습니다
- 🪐 사용자가 이해할 수 없는 오류를 받게 됩니다
💡 우주적 비유: 유효성 검사 = 우주 정거장 방어 시스템:
- 도킹 전 "화물"(데이터)을 검사합니다
- 위험한 객체를 거부합니다
- 우주 쓰레기를 필터링합니다
2. Laravel API에서 유효성 검사를 수행할 위치
주요 접근 방식:
- 컨트롤러 내에서 (빠르지만 코드가 복잡해집니다)
- 폼 요청 (Form Request) (권장, 깔끔한 아키텍처)
3. 컨트롤러 내 유효성 검사
Request 객체의 validate()
메서드를 사용합니다:
<?php
public function store(Request $request)
{
$validated = $request->validate([
'name' => 'required|string|max:255|unique:planets',
'description' => 'required|string',
'size_km' => 'required|integer|min:100|max:500000',
'solar_system' => 'required|string|max:100',
'image_url' => 'nullable|url|max:2048',
'is_habitable' => 'boolean'
]);
// ... 행성 생성
}
인기 있는 유효성 검사 규칙:
규칙 | 설명 | 예시 |
---|---|---|
required |
필수 필드 | 'name' => 'required' |
string |
문자열 값 | 'description' => 'string' |
integer |
정수 | 'size_km' => 'integer' |
min:value |
최소값/길이 | 'size_km' => 'min:100' |
max:value |
최대값/길이 | 'name' => 'max:255' |
unique:table,column |
테이블 내 고유성 | 'name' => 'unique:planets' |
url |
유효한 URL | 'image_url' => 'url' |
boolean |
true/false/1/0 | 'is_habitable' => 'boolean' |
4. 사용자 정의 오류 메시지
기본 오류 텍스트를 변경합니다:
<?php
$validated = $request->validate(
[
'name' => 'required|unique:planets',
'size_km' => 'min:1000'
],
[
'name.required' => '행성 이름은 필수입니다!',
'name.unique' => '해당 행성은 이미 카탈로그에 있습니다',
'size_km.min' => '행성의 직경은 1000km 미만일 수 없습니다'
]
);
오류 응답 예시 (자동 422 Unprocessable Entity):
{
"message": "The given data was invalid.",
"errors": {
"name": ["해당 행성은 이미 카탈로그에 있습니다"],
"size_km": ["행성의 직경은 1000km 미만일 수 없습니다"]
}
}
5. 폼 요청(Form Request) 생성
복잡한 유효성 검사를 위해 별도의 클래스를 생성합니다:
단계 1: 생성
단계 2: app/Http/Requests/StorePlanetRequest.php
편집
<?php
public function authorize()
{
return true; // API의 경우 일반적으로 true
}
public function rules()
{
return [
'name' => 'required|string|max:255|unique:planets',
'description' => 'required|string',
'size_km' => 'required|integer|min:100|max:500000',
'solar_system' => 'required|string|max:100',
'image_url' => 'nullable|url|max:2048',
'is_habitable' => 'boolean'
];
}
public function messages()
{
return [
'name.unique' => '해당 이름을 가진 행성이 이미 존재합니다!',
'size_km.min' => '직경은 100km 미만일 수 없습니다'
];
}
단계 3: 컨트롤러에서 사용
<?php
use App\Http\Requests\StorePlanetRequest;
public function store(StorePlanetRequest $request)
{
// 데이터는 이미 유효성 검사가 완료되었습니다!
$validated = $request->validated();
$planet = Planet::create($validated);
return response()->json($planet, 201);
}
이해했습니다. Laravel 10/11/12와 완벽하게 일치하도록 이 챕터를 수정하고, 더 이상 사용되지 않는 개념이나 플래그(특히 --invokable
)에 대한 모든 언급을 제거하며, 최신 코드만 유지해야 합니다. 불필요한 것은 건드리지 않습니다.
알겠습니다. 다음은 프레임워크의 최신 버전을 정확하게 반영하는 6번째 섹션의 수정된 버전입니다.
6. 사용자 정의 유효성 검사 규칙
행성 이름의 "타당성"을 확인하는 규칙을 생성하겠습니다. Laravel의 표준 규칙은 이름이 "금지"되었는지 확인할 수 없으므로, 우리는 자체적인 로직을 작성할 것입니다.
단계 1: 규칙 생성
Laravel은 규칙 클래스의 "스텁"을 생성하기 위한 Artisan 명령을 제공합니다. 터미널에서 실행해 보겠습니다:
단계 2: app/Rules/ValidPlanetName.php
편집
생성된 파일을 엽니다. 그 구조는 간단하고 명확합니다. 우리의 임무는 validate
메서드 내부에 로직을 구현하는 것입니다.
<?php
namespace App\Rules;
use Closure;
use Illuminate\Contracts\Validation\ValidationRule;
class ValidPlanetName implements ValidationRule
{
/**
* 유효성 검사 규칙을 실행합니다.
*
* @param \Closure(string): \Illuminate\Translation\PotentiallyTranslatedString $fail
*/
public function validate(string $attribute, mixed $value, Closure $fail): void
{
// 우리의 "블랙리스트" 이름
$forbidden = ['Земля 2.0', 'Нибиру', 'Планета X'];
// 입력된 값이 우리의 목록에 있는지,
// 대소문자를 무시하고 확인합니다.
if (in_array(strtolower($value), array_map('strtolower', $forbidden))) {
// 검증에 실패하면,
// 사용자에게 표시될 오류 텍스트와 함께 $fail 함수를 호출합니다.
$fail('이 행성 이름은 사용할 수 없습니다!');
}
}
}
단계 3: 폼 요청(Form Request)에서 사용
이제 사용자 정의 규칙을 사용할 준비가 되었습니다. 클래스의 새 인스턴스를 생성하기만 하면 어떤 폼 요청(Form Request)에서도 이를 포함시킬 수 있습니다.
app/Http/Requests/StorePlanetRequest.php
를 열고 name
필드의 규칙 배열에 new ValidPlanetName
을 추가합니다.
<?php
// app/Http/Requests/StorePlanetRequest.php
namespace App\Http\Requests;
use App\Rules\ValidPlanetName; // <-- 클래스를 임포트하는 것을 잊지 마세요
use Illuminate\Foundation\Http\FormRequest;
class StorePlanetRequest extends FormRequest
{
// ... (authorize 메서드)
public function rules(): array
{
return [
'name' => [
'sometimes',
'string',
'max:255',
'unique:planets',
new ValidPlanetName, // <-- 여기에 우리의 사용자 정의 규칙이 있습니다
],
'description' => 'sometimes|string',
'size_km' => 'sometimes|integer|min:100|max:500000',
'solar_system' => 'sometimes|string|max:100',
'image_url' => 'nullable|url|max:2048',
'is_habitable' => 'sometimes|boolean'
];
}
// ... (messages 메서드)
}
name
필드에 모든 규칙을 순차적으로 적용하고, new ValidPlanetName
에 도달하면 우리의 사용자 정의 로직을 실행할 것입니다.
7. 업데이트를 위한 유효성 검사 (Update)
데이터 업데이트 시의 특징:
레코드를 업데이트할 때 유효성 검사 규칙은 종종 다릅니다. 주요 특징은 현재 업데이트 중인 레코드를 무시해야 하는 고유성 검사입니다.
단계 1: 업데이트를 위한 별도의 폼 요청(Form Request) 생성
단계 2:app/Http/Requests/UpdatePlanetRequest.php
편집
<?php
use Illuminate\Validation\Rule;
public function authorize(): bool
{
return true;
}
public function rules(): array
{
$planet = $this->route('planet'); // 라우트에서 모델 가져오기
return [
'name' => [
'sometimes', // 필드가 요청에 포함된 경우에만 검사
'required',
'string',
'max:255',
Rule::unique('planets')->ignore($planetId),
],
'description' => 'sometimes|required|string',
'size_km' => 'sometimes|required|integer|min:100|max:500000',
// ... 'sometimes'가 적용된 나머지 필드
];
}
<?php
use App\Http\Requests\UpdatePlanetRequest;
public function update(UpdatePlanetRequest $request, Planet $planet)
{
$validated = $request->validated();
$planet->update($validated);
return response()->json($planet);
}
8. Postman에서 유효성 검사 테스트
시나리오 1: 이름 고유성 오류
POST /api/planets
{
"name": "Марс",
"description": "미래 식민지 개척의 목표인 붉은 행성",
"size_km": 6779,
"solar_system": "Solar System",
"is_habitable": false
}
시나리오 2: 잘못된 직경
예상 응답:확인 퀴즈
🚀 장 요약:
귀하는 우주 API를 위한 강력한 보호 시스템을 구축했습니다:
- 🛡️ 기본 및 사용자 정의 유효성 검사 규칙
- 📝 가독성 좋은 오류 메시지
- 🧩 복잡한 시나리오를 위한 Form Request
- ⚙️ 데이터 업데이트를 위한 고유 규칙
이제 귀하의 우주는 보호받습니다! 다음으로 "우주 사고"인 서버 오류를 처리하는 방법을 배울 것입니다.
📌 확인:
- 행성 업데이트를 위한 Form Request를 생성하십시오
- 사용자 정의 이름 검사 규칙을 추가하십시오
- Postman을 통해 오류를 테스트하십시오
⚠️ 유효성 검사가 작동하지 않는 경우:
- 컨트롤러에서 Form Request 연결을 확인하십시오
authorize()
가 true를 반환하는지 확인하십시오- 업데이트 시 고유성을 위해
Rule::unique
를 사용하십시오