【Laravel5】FormRequest의 밸리데이션 결과를 JSON API로 돌려준다
기사가 개인 사이트로 이동했습니다.
개인 사이트/Qiita 모두 동일한 내용을 기재하고 있습니다 (2020/2/24 현재).
개요
예를 들어, 회원을 새로 추가하는 API의 엔드포인트가 있다고 가정합니다.
[POST] https://example.com/api/users
routes/api.phpRoute::resource( 'users', 'Api\UsersController' )->only( ['store'] );
컨트롤러는 다음 상태입니다.
app/Http/Controllers/Api/UsersController.php<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Http\Requests\StoreUserRequest;
use App\Http\Resources\UserResource;
use App\User;
class UsersController extends Controller
{
/**
* 会員追加
*
* @param StoreUserRequest $request
* @return User
*/
public function store( StoreUserRequest $request )
{
return User::create( $request->only( ['name'] ) );
}
}
FormRequest 클래스는 다음 상태입니다.
artisan$ php artisan make:request StoreUserRequest
app/Http/Requests/StoreUserRequest.php<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class StoreUserRequest extends FormRequest
{
public function authorize()
{
return true;
}
public function rules()
{
return [
'name' => 'required',
];
}
public function messages()
{
return [
'name.required' => 'お名前を入力してください。',
];
}
}
위의 API를 두드릴 때 "이름을 입력하십시오."
JSON 형식으로 오류 메시지를 반환하려는 경우를 생각해보십시오.
이 상태로 API를 두드려도 솔직하게 에러 응답이 반환되지 않습니다.
(welcome 페이지의 HTML이 반환됩니다)
원인과 대응
유효성 검사 실패 시 FormRequest 클래스 내에서 리디렉션이 발생하기 때문입니다.
참고 : Laravel5.1.x에서 API를 만들 때 신경 쓰이는 것을 조사했습니다. - Qiita
검증 실패시에도 JSON 형식으로 결과를 반환하도록 대응합니다.
Laravel5.4 이전
FormRequest::response()
를 오버라이드(override) 하는 것으로 대응 가능한 것 같습니다.
StoreUserRequest.php<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Http\JsonResponse; // 追加
class StoreUserRequest extends FormRequest
{
/**
* [override] バリデーション失敗時ハンドリング
*
* @param array $errors
* @return JsonResponse
*/
public function response( array $errors )
{
$response = [
'data' => [],
'status' => 'NG',
'summary' => 'Failed validation.',
'errors' => $errors,
];
return new JsonResponse( $response, 422 );
}
}
Laravel 5.5 이상
FormRequest::response()
는 폐지되었기 때문에 대신FormRequest::failedValidation()
를 오버라이드(override) 하는 것으로 대응합니다.
StoreUserRequest.php<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Contracts\Validation\Validator; // 追加
use Illuminate\Http\Exceptions\HttpResponseException; // 追加
class StoreUserRequest extends FormRequest
{
/**
* [override] バリデーション失敗時ハンドリング
*
* @param Validator $validator
* @throw HttpResponseException
* @see FormRequest::failedValidation()
*/
protected function failedValidation( Validator $validator )
{
$response['data'] = [];
$response['status'] = 'NG';
$response['summary'] = 'Failed validation.';
$response['errors'] = $validator->errors()->toArray();
throw new HttpResponseException(
response()->json( $response, 422 )
);
}
}
실행 결과
이미지는 POSTMAN 캡처입니다.
엔드포인트를 두드려 JSON 응답이 반환되면 OK입니다.

API용 요청 클래스 만들기
API를 작성하는 경우는 응답 형식을 통일하게 된다고 생각하므로,
아래와 같은 추상 클래스를 작성하는 것이 좋을 것입니다.
Laravel5.8 FormRequest에서 검증 실패시 JsonResponse 반환 - Qiita
참고 기사
예를 들어, 회원을 새로 추가하는 API의 엔드포인트가 있다고 가정합니다.
[POST] https://example.com/api/users
routes/api.php
Route::resource( 'users', 'Api\UsersController' )->only( ['store'] );
컨트롤러는 다음 상태입니다.
app/Http/Controllers/Api/UsersController.php
<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Http\Requests\StoreUserRequest;
use App\Http\Resources\UserResource;
use App\User;
class UsersController extends Controller
{
/**
* 会員追加
*
* @param StoreUserRequest $request
* @return User
*/
public function store( StoreUserRequest $request )
{
return User::create( $request->only( ['name'] ) );
}
}
FormRequest 클래스는 다음 상태입니다.
artisan
$ php artisan make:request StoreUserRequest
app/Http/Requests/StoreUserRequest.php
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class StoreUserRequest extends FormRequest
{
public function authorize()
{
return true;
}
public function rules()
{
return [
'name' => 'required',
];
}
public function messages()
{
return [
'name.required' => 'お名前を入力してください。',
];
}
}
위의 API를 두드릴 때 "이름을 입력하십시오."
JSON 형식으로 오류 메시지를 반환하려는 경우를 생각해보십시오.
이 상태로 API를 두드려도 솔직하게 에러 응답이 반환되지 않습니다.
(welcome 페이지의 HTML이 반환됩니다)
원인과 대응
유효성 검사 실패 시 FormRequest 클래스 내에서 리디렉션이 발생하기 때문입니다.
참고 : Laravel5.1.x에서 API를 만들 때 신경 쓰이는 것을 조사했습니다. - Qiita
검증 실패시에도 JSON 형식으로 결과를 반환하도록 대응합니다.
Laravel5.4 이전
FormRequest::response()
를 오버라이드(override) 하는 것으로 대응 가능한 것 같습니다.
StoreUserRequest.php<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Http\JsonResponse; // 追加
class StoreUserRequest extends FormRequest
{
/**
* [override] バリデーション失敗時ハンドリング
*
* @param array $errors
* @return JsonResponse
*/
public function response( array $errors )
{
$response = [
'data' => [],
'status' => 'NG',
'summary' => 'Failed validation.',
'errors' => $errors,
];
return new JsonResponse( $response, 422 );
}
}
Laravel 5.5 이상
FormRequest::response()
는 폐지되었기 때문에 대신FormRequest::failedValidation()
를 오버라이드(override) 하는 것으로 대응합니다.
StoreUserRequest.php<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Contracts\Validation\Validator; // 追加
use Illuminate\Http\Exceptions\HttpResponseException; // 追加
class StoreUserRequest extends FormRequest
{
/**
* [override] バリデーション失敗時ハンドリング
*
* @param Validator $validator
* @throw HttpResponseException
* @see FormRequest::failedValidation()
*/
protected function failedValidation( Validator $validator )
{
$response['data'] = [];
$response['status'] = 'NG';
$response['summary'] = 'Failed validation.';
$response['errors'] = $validator->errors()->toArray();
throw new HttpResponseException(
response()->json( $response, 422 )
);
}
}
실행 결과
이미지는 POSTMAN 캡처입니다.
엔드포인트를 두드려 JSON 응답이 반환되면 OK입니다.

API용 요청 클래스 만들기
API를 작성하는 경우는 응답 형식을 통일하게 된다고 생각하므로,
아래와 같은 추상 클래스를 작성하는 것이 좋을 것입니다.
Laravel5.8 FormRequest에서 검증 실패시 JsonResponse 반환 - Qiita
참고 기사
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Http\JsonResponse; // 追加
class StoreUserRequest extends FormRequest
{
/**
* [override] バリデーション失敗時ハンドリング
*
* @param array $errors
* @return JsonResponse
*/
public function response( array $errors )
{
$response = [
'data' => [],
'status' => 'NG',
'summary' => 'Failed validation.',
'errors' => $errors,
];
return new JsonResponse( $response, 422 );
}
}
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Contracts\Validation\Validator; // 追加
use Illuminate\Http\Exceptions\HttpResponseException; // 追加
class StoreUserRequest extends FormRequest
{
/**
* [override] バリデーション失敗時ハンドリング
*
* @param Validator $validator
* @throw HttpResponseException
* @see FormRequest::failedValidation()
*/
protected function failedValidation( Validator $validator )
{
$response['data'] = [];
$response['status'] = 'NG';
$response['summary'] = 'Failed validation.';
$response['errors'] = $validator->errors()->toArray();
throw new HttpResponseException(
response()->json( $response, 422 )
);
}
}
이미지는 POSTMAN 캡처입니다.
엔드포인트를 두드려 JSON 응답이 반환되면 OK입니다.

API용 요청 클래스 만들기
API를 작성하는 경우는 응답 형식을 통일하게 된다고 생각하므로,
아래와 같은 추상 클래스를 작성하는 것이 좋을 것입니다.
Laravel5.8 FormRequest에서 검증 실패시 JsonResponse 반환 - Qiita
참고 기사
Reference
이 문제에 관하여(【Laravel5】FormRequest의 밸리데이션 결과를 JSON API로 돌려준다), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/junsan50/items/ec7f810decd3b82d3d76텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)