Skip to content

Instantly share code, notes, and snippets.

@akrez
Created July 16, 2024 13:48
Show Gist options
  • Save akrez/b9906fa04b1a4a950d761602b5dd560d to your computer and use it in GitHub Desktop.
Save akrez/b9906fa04b1a4a950d761602b5dd560d to your computer and use it in GitHub Desktop.
Laravel Response Builder (Facade + Builder design pattern)
<?php
namespace App\Contracts;
use Illuminate\Contracts\Support\Responsable;
interface ResponseBuilderContract extends Responsable
{
public function status(int $status): self;
public function getStatus(): int;
public function message(?string $message): self;
public function getMessage(): ?string;
public function data(mixed $data): self;
public function getData(): mixed;
public function errors(mixed $errors): self;
public function getErrors(): mixed;
public function build();
public function toResponse($request);
}
<?php
namespace App\Facades;
use Illuminate\Support\Facades\Facade;
/**
* @method static \App\Supports\ResponseBuilder status(int $status);
* @method static int getStatus();
* @method static \App\Supports\ResponseBuilder message(?string $message);
* @method static ?string getMessage();
* @method static \App\Supports\ResponseBuilder data(mixed $data);
* @method static mixed getData();
* @method static \App\Supports\ResponseBuilder errors(mixed $errors);
* @method static mixed getErrors();
* @method static \App\Supports\Response build();
* @method static \Illuminate\Http\Response toResponse(\Illuminate\Http\Request $request);
*/
class ResponseBuilder extends Facade
{
/**
* Get the registered name of the component.
*
* @return string
*/
protected static function getFacadeAccessor()
{
return 'ResponseBuilder';
}
}
<?php
namespace App\Providers;
use App\Supports\ActiveBlog;
use App\Supports\ResponseBuilder;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*/
public function register(): void
{
//
}
/**
* Bootstrap any application services.
*/
public function boot(): void
{
$this->app->singleton('ResponseBuilder', function () {
return new ResponseBuilder();
});
}
}
<?php
namespace App\Supports;
use App\Contracts\ResponseBuilderContract;
use Illuminate\Contracts\Support\Responsable;
class Response implements Responsable
{
public $status;
public $message;
public $data;
public $errors;
public function __construct(ResponseBuilderContract $builder)
{
$this->status = $builder->getStatus();
$this->message = $builder->getMessage();
$this->data = $builder->getData();
$this->errors = $builder->getErrors();
}
public function toResponse($request)
{
return response([
'message' => $this->message,
'data' => $this->data,
'errors' => $this->errors,
], $this->status);
}
}
<?php
namespace App\Supports;
use App\Contracts\ResponseBuilderContract;
use Illuminate\Support\Facades\Lang;
class ResponseBuilder implements ResponseBuilderContract
{
private int $status;
private ?string $message;
private mixed $data;
private mixed $errors;
public function __construct()
{
$this->reset();
}
public function reset(): self
{
$this->status = 200;
$this->message = 'OK';
$this->data = [];
$this->errors = [];
return $this;
}
public function status(int $status): self
{
$this->status = $status;
return $this;
}
public function getStatus(): int
{
return $this->status;
}
public function message(?string $message): self
{
$this->message = (Lang::has($message) ? __($message) : $message);
return $this;
}
public function getMessage(): ?string
{
return $this->message;
}
public function data(mixed $data): self
{
$this->data = $data;
return $this;
}
public function getData(): mixed
{
return $this->data;
}
public function errors(mixed $errors): self
{
$this->errors = $errors;
return $this;
}
public function getErrors(): mixed
{
return $this->errors;
}
public function build(): \App\Supports\Response
{
$response = new Response($this);
$this->reset();
return $response;
}
public function toResponse($request): \Illuminate\Http\Response
{
return $this->build()->toResponse($request);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment