Package for standardizing the responses from the API of your Symfony based applications.
- Installation
- Using
- Copyright and License
To get the latest version of API Response
, simply require the project using Composer:
$ composer require andrey-helldar/api-response
This command will automatically install the latest version of the package for your environment.
Instead, you may of course manually update your require
block and run composer update
if you so choose:
{
"require": {
"andrey-helldar/api-response": "^6.0"
}
}
Alright! Use api_response()
helper.
Package version | PHP min version | Symfony version | Support | Links |
---|---|---|---|---|
^4.0 | 5.6.9 | ^3.0, ^4.0 | --- | |
^4.4.1 | 5.6.9 | ^3.0, ^4.0, ^5.0 | --- | |
^5.0 | 7.1.3 | ^4.0, ^5.0 | --- | |
^6.0 | 7.3 | ^4.0, ^5.0 | Upgrade guide |
return api_response(null, 304);
return with code 304:
{
"data": null
}
return api_response(304);
return with code 200:
{
"data": 304
}
return api_response('qwerty');
return with code 200:
{
"data": "qwerty"
}
return api_response('qwerty', 400);
return with code 400:
{
"error": {
"type": "Exception",
"data": "qwerty"
}
}
return api_response(304, 400);
return with code 400:
{
"error": {
"type": "Exception",
"data": 304
}
}
$data = [
[
'title' => 'Title #1',
'description' => 'Description #1',
],
[
'title' => 'Title #2',
'description' => 'Description #2',
],
];
return api_response($data, 400);
return with code 400:
{
"error": {
"type": "Exception",
"data": [
{
"title": "Title #1",
"description": "Description #1"
},
{
"title": "Title #2",
"description": "Description #2"
}
]
}
}
return api_response($data, 200);
return with code 200:
{
"data": [
{
"title": "Title #1",
"description": "Description #1"
},
{
"title": "Title #2",
"description": "Description #2"
}
]
}
If the first parameter is a number, then the decryption of the error by code will be return. In other cases, the value of the passed variable will be return.
return api_response('title', 200, ['foo' => 'bar']);
return with code 200:
{
"data": "title",
"foo": "bar"
}
return with code 400:
{
"error": {
"type": "Exception",
"data":"ok"
},
"foo": "bar"
}
return api_response(['data' => 'foo', 'bar' => 'baz']);
return with code 200:
{
"data": "foo",
"bar": "baz"
}
return with code 400:
{
"error": {
"type": "Exception",
"data":"foo"
},
"bar": "baz"
}
If you do not want to wrap the response in the data
key, then you need to pass the false
value to the 5th parameter of the function:
use Helldar\ApiResponse\Services\Response;
use Symfony\Component\HttpFoundation\JsonResponse;
/**
* Return a new response from the application.
*
* @param mixed|null $data
* @param int $status_code
* @param array $with
* @param array $headers
* @param bool $use_data
*
* @return Symfony\Component\HttpFoundation\JsonResponse
*/
function api_response(
$data = null,
int $status_code = 200,
array $with = [],
array $headers = [],
bool $use_data = true
)
{
return Response::init()
->data($data, $status_code, $use_data)
->with($with)
->headers($headers)
->response();
}
return api_response(null, 304, [], [], false);
return with code 304:
{}
return api_response(304, 200, [], [], false);
return with code 200:
304
return api_response('qwerty', 200, [], [], false);
return with code 200:
"qwerty"
return api_response('qwerty', 400, [], [], false);
return with code 400:
{
"error": {
"type": "Exception",
"data": "qwerty"
}
}
return api_response(304, 400, [], [], false);
return with code 400:
{
"error": {
"type": "Exception",
"data": 304
}
}
$data = [
[
'title' => 'Title #1',
'description' => 'Description #1',
],
[
'title' => 'Title #2',
'description' => 'Description #2',
],
];
return api_response($data, 400, [], [], false);
return with code 400:
{
"error": {
"type": "Exception",
"data": [
{
"title": "Title #1",
"description": "Description #1"
},
{
"title": "Title #2",
"description": "Description #2"
}
]
}
}
return api_response($data, 200, [], [], false);
return with code 200:
[
{
"title": "Title #1",
"description": "Description #1"
},
{
"title": "Title #2",
"description": "Description #2"
}
]
If the first parameter is a number, then the decryption of the error by code will be return. In other cases, the value of the passed variable will be return.
return api_response('title', 200, ['foo' => 'bar'], [], false);
return with code 200:
{
"data": "title",
"foo": "bar"
}
return with code 400:
{
"error": {
"type": "Exception",
"data":"ok"
},
"foo": "bar"
}
return api_response(['data' => 'foo', 'bar' => 'baz'], 200, [], [], false);
return with code 200:
{
"data": "foo",
"bar": "baz"
}
return with code 400:
{
"error": {
"type": "Exception",
"data":"foo"
},
"bar": "baz"
}
class FooException extends \Exception
{
public function __construct()
{
parent::__construct('Foo', 405);
}
}
class BarException extends \Exception
{
public function __construct()
{
parent::__construct('Bar', 0);
}
}
$foo = new FooException();
$bar = new BarException();
return api_response($foo);
return with code 405:
{
"error": {
"type": "FooException",
"data": "Foo"
}
}
return api_response($foo, 408);
return with code 408:
{
"error": {
"type": "FooException",
"data": "Foo"
}
}
return api_response($bar);
return with code 400:
{
"error": {
"type": "BarException",
"data": "Bar"
}
}
return api_response($bar, 408);
return with code 408:
{
"error": {
"type": "BarException",
"data": "Bar"
}
}
You can also add additional data:
return api_response($foo, ['foo' => 'Bar']);
return with code 405:
{
"error": {
"type": "FooException",
"data": "Foo"
},
"foo": "Bar"
}
To call the function when errors occur, you need to make changes to file app/Exceptions/Handler.php
:
use Illuminate\Auth\AuthenticationException;
use Illuminate\Contracts\Support\Responsable;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Illuminate\Foundation\Http\Exceptions\MaintenanceModeException;
use Illuminate\Http\Exceptions\HttpResponseException;
use Illuminate\Routing\Router;
use Illuminate\Support\Arr;
use Illuminate\Validation\ValidationException;
use Symfony\Component\HttpFoundation\JsonResponse;
use Throwable;
class Handler extends ExceptionHandler
{
/**
* Render an exception into an HTTP response.
*
* @param \Illuminate\Http\Request $request
* @param \Throwable $e
*
* @return \Symfony\Component\HttpFoundation\Response
*
* @throws \Throwable
*/
public function render($request, Throwable $e)
{
if ($this->isJson($request) && $e instanceof MaintenanceModeException) {
return api_response(__('Maintenance Mode'), 503);
}
if (\method_exists($e, 'render') && $response = $e->render($request)) {
return Router::toResponse($request, $response);
} elseif ($e instanceof Responsable) {
return $e->toResponse($request);
}
$e = $this->prepareException($e);
if ($e instanceof HttpResponseException) {
return $e->getResponse();
} elseif ($e instanceof AuthenticationException) {
return $this->unauthenticated($request, $e);
} elseif ($e instanceof ValidationException) {
return $this->convertValidationExceptionToResponse($e, $request);
}
return $this->isJson($request)
? $this->prepareJsonResponse($request, $e)
: $this->prepareResponse($request, $e);
}
protected function invalidJson($request, ValidationException $exception)
{
return api_response($exception);
}
protected function unauthenticated($request, AuthenticationException $exception)
{
return $this->isJson($request)
? api_response($exception)
: redirect()->guest(route('login'));
}
/**
* @param \Illuminate\Http\Request $request
* @param Throwable|Symfony\Component\HttpFoundation\JsonResponse $response
*
* @return bool
*/
protected function isJson($request, $response = null): bool
{
return $request->expectsJson() || $request->isJson() || $request->is('api*') || $response instanceof JsonResponse;
}
protected function prepareJsonResponse($request, Throwable $e)
{
return api_response(
$this->convertExceptionToArray($e),
$this->isHttpException($e) ? $e->getStatusCode() : 500,
[],
$this->isHttpException($e) ? $e->getHeaders() : []
);
}
protected function convertExceptionToArray(Throwable $e)
{
$converted = parent::convertExceptionToArray($e);
return config('app.debug')
? $converted
: Arr::get($converted, 'message');
}
}
API Response
was written by Andrey Helldar, and is licensed under the MIT License.