thombas/revised-service-pattern

A package that adds a service pattern which extends from the established models.

1.0.1 2025-05-04 11:40 UTC

This package is auto-updated.

Last update: 2025-06-04 11:51:18 UTC


README

Latest Version on Packagist Total Downloads License: MIT Tests

🚀 Introduction

Revised Service Pattern is a Laravel package that extends Laravel’s native HTTP client with a clean, structured singleton-based service pattern for interacting with third-party RESTful APIs.

It’s built for developers who want:

  • ✅ Rapid third-party API integration
  • ✅ Organized endpoint structure
  • ✅ Full compatibility with Laravel's HTTP tools

✨ Features

  • Lightweight and framework-friendly
  • Singleton-based API access pattern
  • Extends Laravel’s Http facade for consistency
  • Auto-discovered endpoints and templates
  • Artisan commands for bootstrapping services, templates, and stubs
  • Testing-friendly with no boilerplate or conditional logic pollution

📦 Installation

composer require thombas/revised-service-pattern

🛠️ Getting Started

1️⃣ Create a Base Service

Define your base service to handle global API config (e.g. base URL, headers, auth).

use Thombas\RevisedServicePattern\Services\RestApiService;

class MyApiService extends RestApiService
{
    protected function setup(): static
    {
        return $this->baseUrl('https://api.example.com')->asJson();
    }
}

2️⃣ Create Endpoint Services

Endpoints extend your base service. Each represents one API route and defines method, URL, and parameters.

class FetchUserEndpoint extends MyApiService
{
    protected function setup(): static
    {
        return parent::setup()
            ->setUrl('user')
            ->setMethod(ServiceMethodEnum::Get)
            ->setParamaters(['id' => 123]);
    }
}

Best Practice: Keep one class per endpoint for maintainability and clear logic separation.

⚙️ Artisan Commands

Scaffold services and templates using built-in Artisan commands.

php artisan template:create OpenWeather

Add an endpoint directly:

php artisan template:create OpenWeather --endpoint=Thunderstorms

Use subdirectories for grouping:

php artisan template:create OpenWeather --endpoint=Thunderstorms/Frequency

Note: Both / and \ are accepted as path separators.

📡 Endpoint Lifecycle

Endpoint classes support full control over request logic using lifecycle hooks:

__construct()

Receive parameters:

public function __construct(protected string $userId)
{
    parent::__construct();
}

setup()

Configure request:

protected function setup(): static
{
    return parent::setup()
        ->setUrl('user')
        ->setMethod(ServiceMethodEnum::Get)
        ->setParamaters(['id' => 123]);
}

before()

Optional pre-request logic (e.g. caching):

protected function before(): ?Response
{
    return Cache::get("user_{$this->userId}");
}

validate()

Inspect API response and throw errors:

protected function validate(Response $response): void
{
    if ($response->json('status') !== 'success') {
        throw new \Exception("API error: " . $response->json('message'));
    }
}

after()

Post-request processing (e.g. caching, saving):

protected function after(Response $response): void
{
    Cache::put("user_{$this->userId}", $response->json('data'), now()->addMinutes(10));
}

format()

Return response in preferred format:

protected function format(Response $response): mixed
{
    return [
        'id' => $response->json('data.id'),
        'name' => $response->json('data.full_name'),
    ];
}

🧩 Accessing Endpoints

Use your service to statically call any registered endpoint:

$response = MyApiService::fetchUser();
  • Endpoints must be in the same directory as your base service.
  • Each endpoint class name must be unique to avoid conflicts.

📦 Templates

Templates structure and validate input payloads for your endpoints.

Example

public function __construct(public string $code = 'test')
{
    parent::__construct();
}

public function __invoke(): array
{
    return ['Code' => $this->code];
}

protected function validator(): ?\Illuminate\Validation\Validator
{
    return \Illuminate\Support\Facades\Validator::make(
        ['code' => $this->code],
        ['code' => ['required', 'min:3', 'max:255']]
    );
}

Use as a parameter:

$response = MyApiService::fetchUser(new FetchUserTemplate());

🧪 Testing

Run PHPUnit tests with:

vendor/bin/phpunit

📜 Changelog

Check out the CHANGELOG for version history.

🤝 Contributing

Contributions are welcome!
See CONTRIBUTING.md.

🔒 Security

For security concerns, please refer to our security policy.

🏆 Credits

🪪 License

Licensed under the MIT License.