Skip to content

Services

Overview

Services contain business logic extracted from controllers and models. They live in app/Services/ and are organized by domain. Services follow either a single-action or multi-method pattern.


Folder Structure

app/Services/
├── Asset/                     # File upload + CDN
│   ├── ImageKitService.php    # Multi-method: prepare, upload
│   ├── CompressService.php    # Single-action: compress
│   ├── ResizeService.php      # Single-action: resize
│   └── ConversionService.php  # Single-action: convertToWebp
├── Codegen/                   # Barcode + QR generation
│   ├── GenerateBarcode.php    # Single-action: generate
│   └── GenerateQRCode.php     # Single-action: generate
├── Common/                    # Cross-cutting services
│   └── IdentifierAppService.php  # Static: isSetup, seeder, initial
├── Otp/                       # OTP generation + verification
│   ├── Generate.php           # Single-action: handle
│   └── Verify.php             # Single-action: handle
└── Platform/Pipeline/         # Pipeline orchestration

Patterns

Single-Action Service

Used when the service does one thing. The class name describes the action and exposes a handle() method:

php
namespace App\Services\Otp;

class Generate
{
    public static function handle(string $email, array $meta = []): Otp
    {
        // Generate code, store in database
    }
}

Calling convention:

php
$otp = Generate::handle($email);

Multi-Method Service

Used when the service has multiple related operations:

php
namespace App\Services\Asset;

class ImageKitService
{
    public function prepare(UploadedFile $file, array $options = []): array { ... }
    public function upload(string $contents, string $fileName, array $options = []): array { ... }
    public function delete(string $fileId): bool { ... }
}

Calling convention:

php
$service = app(ImageKitService::class);
$prepared = $service->prepare($file);
$result = $service->upload($prepared['contents'], $prepared['file_name']);

Static Helper Service

Used for stateless utility services with no dependencies:

php
namespace App\Services\Common;

class IdentifierAppService
{
    public static function isSetup(): bool { ... }
    public static function isSeeder(): bool { ... }
}

Rules

RuleDescription
No HTTP concernsServices don't touch request, response, or session
No stateServices are stateless — all state lives in models or stores
InjectableUse constructor injection for dependencies
TestableServices should be testable without Laravel bootstrapping
Single responsibilityOne service = one concern

Creating a New Service

bash
# Single-action
php artisan make:class Services/Domain/ActionName

# Multi-method
php artisan make:class Services/Domain/NameService

Key Files

FilePurpose
app/Services/Asset/ImageKitService.phpFile upload + CDN orchestration
app/Services/Otp/Generate.phpOTP code generation
app/Services/Common/IdentifierAppService.phpApplication state checks
app/Services/Codegen/GenerateBarcode.phpBarcode generation