한 가지 형태로 통일시켜줘야 프론트엔드 개발자가 작업하시기가 편합니다. 원래, http code로 구분했었었는데, 다른 분은 reponse 형태를 통일시켜 달라고 하셔서 작업했습니다.
api response 예
{
"status": "Success",
"message": "상품 조회 성공",
"data": {
"product": {
"id": 1,
"created_at": "2023-03-25 14:33:33",
}
}
}
(당연히 config/app.php
에도 등록해줘야함)
<?php
# Providers/ApiResponseServiceProvider.php
declare(strict_types=1);
namespace App\Providers;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Response;
use Illuminate\Support\ServiceProvider;
use JustSteveKing\StatusCode\Http;
class ApiResponseServiceProvider extends ServiceProvider
{
/**
* Register services.
*
* @return void
*/
public function register(): void
{
}
/**
* Bootstrap services.
*
* @return void
*/
public function boot(): void
{
Response::macro('success', function (array|string $data, string $message = null, int $code = 200): JsonResponse {
return Response::json([
'status' => 'Success',
'message' => $message,
'data' => $data
], $code);
});
Response::macro('error', function (string $message, int|Http $code, array|string $data = null): JsonResponse {
return Response::json([
'status' => 'Error',
'message' => $message,
'data' => $data
], $code);
});
}
}
사용예
public function show(Store $store): JsonResponse
{
$this->authorize('show', $store);
return Response::success([
'store' => new StoreResource($store->load('photos')),
], '상점 조회 성공');
}
middleware, validation error까지 모두 통일시킬 것.
<?php
declare(strict_types=1);
namespace App\Exceptions;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Response;
use Illuminate\Validation\ValidationException;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
class Handler extends ExceptionHandler
{
/**
* The list of the inputs that are never flashed to the session on validation exceptions.
*
* @var array<int, string>
*/
protected $dontFlash = [
'current_password',
'password',
'password_confirmation',
];
/**
* Register the exception handling callbacks for the application.
*/
public function register(): void
{
$this->renderable(function (AuthenticationException $e, $request) {
if ($request->is('api/*')) {
return Response::error('인증된 사용자가 아닙니다', 401, []);
}
});
$this->renderable(function (AccessDeniedHttpException $e, $request) {
if ($request->is('api/*')) {
return Response::error('권한이 없어 요청이 거부되었습니다.', 403, []);
}
});
$this->renderable(function (NotFoundHttpException $e, $request) {
if ($request->is('api/*')) {
return Response::error($e->getMessage(), 404, []);
}
});
}
/**
* Convert a validation exception into a JSON response.
*
* @param ValidationException $e
* @param Request $request
* @return JsonResponse
*/
public function convertValidationExceptionToResponse(ValidationException $e, $request): JsonResponse
{
if ($request->expectsJson()) {
return response()->json([
"status" => 'Error',
"message" => "유효성 검사 실패",
"data" => $e->errors()
], 422);
}
parent::convertValidationExceptionToResponse($e, $request);
}
}