In this article, we’ll explore how to modify API output in Laravel applications. We’ll walk you through the steps involved, drawing upon a method successfully implemented in a previous project.
I could not find the original source of this code, but because we used this method in a project, I wanted to write this experience here.
1. Create a BaseCollection file in this path: “app/Http/Resources/BaseCollection.php”
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\ResourceCollection;
class BaseCollection extends ResourceCollection
{
private array $pagination;
/**
* @param $resource
*/
public function __construct($resource)
{
$this->pagination = [
'total' => $resource->total(),
"pages" => $resource->lastPage(),
"limit" => $resource->perPage(),
"page" => $resource->currentPage(),
"prev" => $resource->previousPageUrl(),
"next" => $resource->nextPageUrl()
];
$resource = $resource->getCollection();
parent::__construct($resource);
}
/**
* @param $request
* @return array
*/
public function with($request): array
{
return [
"status" => "OK",
"code" => 200,
"error_message" => "",
'meta' => $this->pagination
];
}
/**
* @param $request
* @return array
*/
public function toArray($request): array
{
return [
'data' => $this->collection,
];
}
}
2. Next, Create a BaseResource file in this path: “app/Http/Resources/BaseResource.php”
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class BaseResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
return $this->resource;
}
/**
* @param $request
* @return array
*/
public function with($request): array
{
return [
"status" => "OK",
"code" => 200,
"errorMessage" => "",
];
}
}
So, to use it, We must add the following code in “app/Providers/AppServiceProvider.php”
namespace App\Providers;
use App\Http\Resources\BaseCollection;
use Illuminate\Support\Facades\Response;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*
* @return void
*/
public function register()
{
//
}
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
Response::macro('apiSuccessResponseWithPaginator', function ($data, $collection = null) {
if (is_null($collection)) {
return new BaseCollection($data);
}
return new $collection($data);
});
Response::macro('apiSuccessResponse', function ($data, $collection = null) {
if (is_null($collection)) {
$res = [
"status" => "OK",
"code" => 200,
"errorMessage" => "",
"data" => $data
];
return response()->json($res);
}
return new $collection($data);
});
Response::macro('apiFailResponse', function ($status, $message, $code = 422, $data = null) {
$res = [
"status" => $status,
"code" => $code,
"errorMessage" => $message,
"data" => $data
];
return response($res, $code);
});
}
}
Now we can use our custom response like the following example:
public function list(): mixed
{
return Response::apiSuccessResponseWithPaginator(
$this->task->paginate(config('daily.per_page'))
);
}