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 orchestrationPatterns
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
| Rule | Description |
|---|---|
| No HTTP concerns | Services don't touch request, response, or session |
| No state | Services are stateless — all state lives in models or stores |
| Injectable | Use constructor injection for dependencies |
| Testable | Services should be testable without Laravel bootstrapping |
| Single responsibility | One 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/NameServiceKey Files
| File | Purpose |
|---|---|
app/Services/Asset/ImageKitService.php | File upload + CDN orchestration |
app/Services/Otp/Generate.php | OTP code generation |
app/Services/Common/IdentifierAppService.php | Application state checks |
app/Services/Codegen/GenerateBarcode.php | Barcode generation |