Last active
December 8, 2024 15:09
-
-
Save jfreites/47ffecce49902ec200d5b3dbb7acccd2 to your computer and use it in GitHub Desktop.
Laravel API response trait
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Traits\Http; | |
use Error; | |
use Exception; | |
use Illuminate\Http\JsonResponse; | |
use Illuminate\Http\Resources\Json\JsonResource; | |
use Illuminate\Http\Resources\Json\ResourceCollection; | |
use Illuminate\Validation\ValidationException; | |
trait ApiResponse | |
{ | |
protected function apiResponse(array $data = [], $statusCode = 200, $headers = []): JsonResponse | |
{ | |
// https://laracasts.com/discuss/channels/laravel/pagination-data-missing-from-api-resource | |
$result = $this->parseGivenData($data, $statusCode, $headers); | |
return response()->json($result['content'], $result['statusCode'], $result['headers']); | |
} | |
private function parseGivenData($data = [], $statusCode = 200, $headers = []): array | |
{ | |
$responseStructure = [ | |
'success' => $data['success'], | |
'message' => $data['message'] ?? null, | |
'result' => $data['result'] ?? null, | |
]; | |
if (isset($data['errors'])) { | |
$responseStructure['errors'] = $data['errors']; | |
} | |
if (isset($data['status'])) { | |
$statusCode = $data['status']; | |
} | |
if (isset($data['exception']) && ($data['exception'] instanceof Error || $data['exception'] instanceof Exception)) { | |
if (! app()->environment('production')) { | |
$exceptionData = [ | |
'message' => $data['exception']->getMessage(), | |
'file' => $data['exception']->getFile(), | |
'line' => $data['exception']->getLine(), | |
'code' => $data['exception']->getCode(), | |
'trace' => $data['exception']->getTrace(), | |
]; | |
Log::debug('Api exception info', $exceptionData); | |
$statusCode = 500; | |
} | |
} | |
if ($data['success'] === false) { | |
if (isset($data['error_code'])) { | |
$responseStructure['error_code'] = $data['error_code']; | |
} else { | |
$responseStructure['error_code'] = 1; | |
} | |
} | |
return ['content' => $responseStructure, 'statusCode' => $statusCode, 'headers' => $headers]; | |
} | |
protected function respondWithResource( | |
JsonResource $resource, | |
$message = null, | |
$statusCode = 200, | |
$headers = [] | |
): JsonResponse { | |
// https://laracasts.com/discuss/channels/laravel/pagination-data-missing-from-api-resource | |
return $this->apiResponse( | |
[ | |
'success' => true, | |
'result' => $resource, | |
'message' => $message, | |
], $statusCode, $headers | |
); | |
} | |
protected function respondWithResourceCollection( | |
ResourceCollection $resourceCollection, | |
$message = null, | |
$statusCode = 200, | |
$headers = [] | |
): JsonResponse { | |
// https://laracasts.com/discuss/channels/laravel/pagination-data-missing-from-api-resource | |
return $this->apiResponse( | |
[ | |
'success' => true, | |
'message' => $message, | |
'result' => $resourceCollection->response()->getData(), | |
], $statusCode, $headers | |
); | |
} | |
protected function respondSuccess($message = ''): JsonResponse | |
{ | |
return $this->apiResponse(['success' => true, 'message' => $message]); | |
} | |
protected function respondCreated($data): JsonResponse | |
{ | |
return $this->apiResponse($data, 201); | |
} | |
protected function respondNoContent($message = 'No Content Found'): JsonResponse | |
{ | |
return $this->apiResponse(['success' => false, 'message' => $message], 200); | |
} | |
protected function respondNotFound($message = 'Not Found'): JsonResponse | |
{ | |
return $this->respondError($message, 404); | |
} | |
protected function respondUnAuthorized($message = 'Unauthorized'): JsonResponse | |
{ | |
return $this->respondError($message, 401); | |
} | |
protected function respondForbidden($message = 'Forbidden'): JsonResponse | |
{ | |
return $this->respondError($message, 403); | |
} | |
protected function respondError( | |
string $message, | |
int $statusCode = 400, | |
Exception $exception = null, | |
int $errorCode = 1 | |
): JsonResponse { | |
return $this->apiResponse( | |
[ | |
'success' => false, | |
'message' => $message ?? 'There was an internal error, Please try again later.', | |
'exception' => $exception, | |
'error_code' => $errorCode, | |
], $statusCode | |
); | |
} | |
protected function respondInternalError($message = 'Internal Error'): JsonResponse | |
{ | |
return $this->respondError($message, 500); | |
} | |
protected function respondValidationErrors(ValidationException $exception): JsonResponse | |
{ | |
return $this->apiResponse( | |
[ | |
'success' => false, | |
'message' => $exception->getMessage(), | |
'errors' => $exception->errors(), | |
], | |
422 // Change to an Enum | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment