Package for standardizing the responses from the API of your Symfony based applications.
- To 10.x From 9.x
- To 9.x From 8.x and from the
andrey-helldar/api-response
package - To 8.x From 7.x
- To 7.x From 6.x
- To 6.x From 5.x
To get the latest version of API Response
, simply require the project using Composer:
$ composer require dragon-code/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": {
"dragon-code/api-response": "^9.1"
}
}
Alright! Use api_response()
helper.
Package version | PHP min version | Symfony version | Support | Links |
---|---|---|---|---|
^9.0 | 7.2.5 | ^4.0, ^5.0, ^6.0 | Upgrade guide | |
^8.0 | 7.2.5 | ^4.0, ^5.0 | Upgrade guide | |
^7.0 | 7.2.5 | ^4.0, ^5.0 | Upgrade guide | |
^6.0 | 7.3 | ^4.0, ^5.0 | Upgrade guide | |
^5.0 | 7.1.3 | ^4.0, ^5.0 | --- | |
^4.4.1 | 5.6.9 | ^3.0, ^4.0, ^5.0 | --- | |
^4.0 | 5.6.9 | ^3.0, ^4.0 | --- |
// php 7.4 and below
return api_response(null, 304);
// php 8.0
return api_response( status_code: 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);
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.
// php 7.4 and below
return api_response('title', 200, ['foo' => 'bar']);
// or
return api_response('title', null, ['foo' => 'bar']);
// php 8.0
return api_response('title', with: ['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"
}
Since the goal of the package is to unify all the answers, we moved the variable definitions into a static function. So, for example, to enable or disable wrapping content in
the data
key, you need to call the wrapped
or withoutWrap
method:
use DragonCode\ApiResponse\Services\Response;
Response::withoutWrap();
// php 7.4 and below
return api_response(null, 304);
// php 8.0
return api_response( status_code: 304 );
return with code 304:
[]
return api_response(304, 200);
return with code 200:
304
return api_response('qwerty', 200);
return with code 200:
"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);
// or
return api_response($data);
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.
// php 7.4 and below
return api_response('title', 200, ['foo' => 'bar']);
// php 8.0
return api_response('title', with: ['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"
}
In some cases, when returning answers, you must also give additional data. Such as stack trace, for example.
To prevent this data from getting in response to production, you can globally set a label to show or hide this data:
use DragonCode\ApiResponse\Services\Response;
env('APP_DEBUG')
? Response::allowWith()
: Response::withoutWith();
Now all responses will not contain the additional data being passed.
For example:
// php 7.4 and below
return api_response('title', 200, ['foo' => 'bar']);
// or
return api_response('title', null, ['foo' => 'bar']);
// php 8.0
return api_response('title', with: ['foo' => 'bar']);
return with code 200:
{
"data": "title"
}
return with code 400:
{
"error": {
"type": "Exception",
"data": "ok"
}
}
Note: The
$with
parameter is also responsible for displaying server-side error messages.In this case, Http errors will be displayed without masking.
For example:
use DragonCode\ApiResponse\Services\Response;
Response::allowWith();
$e = new Exception('Foo', 0);
return api_response($e);
return with code 500:
{
"error": {
"type": "Exception",
"data": "Foo"
}
}
and
use DragonCode\ApiResponse\Services\Response;
Response::withoutWith();
$e = new Exception('Foo', 0);
return api_response($e);
return with code 500:
{
"error": {
"type": "Exception",
"data": "Whoops! Something went wrong."
}
}
return with if code >=400 and < 500:
{
"error": {
"type": "Exception",
"data": "Foo"
}
}
class FooException extends \Exception
{
public function __construct()
{
parent::__construct('Foo', 405);
}
}
class BarException extends \Exception
{
public function __construct()
{
parent::__construct('Bar');
}
}
$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, 405, ['foo' => 'Bar']);
// or
return api_response($foo, 0, ['foo' => 'Bar']);
return with code 405:
{
"error": {
"type": "FooException",
"data": "Foo"
},
"foo": "Bar"
}
If you use the Laravel or Lumen framework, you can update the extends
in the app\Exceptions\Handler.php
file depending on your application version and needs:
Version \ Type | API + WEB | Only API |
---|---|---|
9.x | DragonCode\ApiResponse\Exceptions\Laravel\Nine\Handler as ExceptionHandler |
DragonCode\ApiResponse\Exceptions\Laravel\Nine\ApiHandler as ExceptionHandler |
8.x | DragonCode\ApiResponse\Exceptions\Laravel\Eight\Handler as ExceptionHandler |
DragonCode\ApiResponse\Exceptions\Laravel\Eight\ApiHandler as ExceptionHandler |
7.x | DragonCode\ApiResponse\Exceptions\Laravel\Seven\Handler as ExceptionHandler |
DragonCode\ApiResponse\Exceptions\Laravel\Seven\ApiHandler as ExceptionHandler |
If you did not add anything to this file, then delete everything properties and methods.
For example, as a result, a clean file will look like this:
<?php
namespace App\Exceptions;
use DragonCode\ApiResponse\Exceptions\Laravel\Nine\Handler as ExceptionHandler;
class Handler extends ExceptionHandler
{
//
}
More examples:
<?php
namespace App\Exceptions;
// use DragonCode\ApiResponse\Exceptions\Laravel\Nine\Handler as ExceptionHandler;
use DragonCode\ApiResponse\Exceptions\Laravel\Nine\ApiHandler as ExceptionHandler;
// use DragonCode\ApiResponse\Exceptions\Laravel\Eight\Handler as ExceptionHandler;
// use DragonCode\ApiResponse\Exceptions\Laravel\Eight\ApiHandler as ExceptionHandler;
// use DragonCode\ApiResponse\Exceptions\Laravel\Seven\Handler as ExceptionHandler;
// use DragonCode\ApiResponse\Exceptions\Laravel\Seven\ApiHandler as ExceptionHandler;
class Handler extends ExceptionHandler
{
//
}
Now, if you pass a resource object or validator object, it will also be rendered beautifully:
use Illuminate\Http\Resources\Json\JsonResource;
/** @mixin \Tests\Fixtures\Laravel\Model */
final class Resource extends JsonResource
{
public function toArray($request)
{
return [
'foo' => $this->foo,
'bar' => $this->bar,
];
}
public function with($request)
{
return ['baz' => 'Baz'];
}
}
$model = Model::first();
$resource = MyResource::make($model);
return api_response($resource);
return with code 200:
{
"data": {
"foo": "Foo",
"bar": "Bar"
},
"baz": "Baz"
}
If Response::withoutWrap()
{
"foo": "Foo",
"bar": "Bar",
"baz": "Baz"
}
If Response::withoutWith()
{
"data": {
"foo": "Foo",
"bar": "Bar"
}
}
If Response::withoutWith()
and Response::withoutWrap()
{
"foo": "Foo",
"bar": "Bar"
}
$data = [
'foo' => 'Foo',
'bar' => 123,
'baz' => 'https://foo.example'
];
$rules = [
'foo' => ['required'],
'bar' => ['integer'],
'baz' => ['sometimes', 'url'],
];
$validator = Validator::make($data, $rules);
return $validator->fails()
? new ValidationException($validator)
: $validator->validated();
If success:
{
"data": {
"foo": "Foo",
"bar": 123,
"baz": "https://foo.example"
}
}
If failed:
{
"error": {
"type": "ValidationException",
"data": {
"foo": ["The foo field is required."],
"bar": ["The bar must be an integer."],
"baz": ["The baz format is invalid."]
}
}
}
This package is licensed under the MIT License.