Change API response in Laravel

Change API response in Laravel

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'))
    );
}

 

Leave a Reply

Your email address will not be published. Required fields are marked *