Structure Laravel applications using the Service Provider pattern with Model, DTO, Service, Controller, FormRequest, Resource, Policy, Event, and Test artifacts. Use when scaffolding a new service, creating a Model with business logic, designing DTOs, structuring service classes, registering providers, or organizing Laravel code by domain. Triggers on service provider, model creation, DTO, service class, controller pattern, form request, or resource controller.
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
A direct command skips the review prompt. Inspect the source before running it.
The command stays on one line. Scroll horizontally to inspect it before copying.
Prefer a local copy? Download the files currently available to SkillsMP.
File Explorer
5 files
Showing SKILL.md
SKILL.md
Source instructions · Read-only preview
name
service-provider-architecture
description
Structure Laravel applications using the Service Provider pattern with Model, DTO, Service, Controller, FormRequest, Resource, Policy, Event, and Test artifacts. Use when scaffolding a new service, creating a Model with business logic, designing DTOs, structuring service classes, registering providers, or organizing Laravel code by domain. Triggers on service provider, model creation, DTO, service class, controller pattern, form request, or resource controller.
Service Provider Architecture Skill
A comprehensive guide for structuring Laravel applications using the Service Provider pattern. Each domain entity is organized into a consistent set of artifacts — Model, DTO, Service, Controller, FormRequest, Resource, Policy, Event, Listener, and ServiceProvider — ensuring separation of concerns, testability, and maintainability.
Target users: Full-stack Laravel + React (Inertia.js) developers who want clean, domain-organized code with predictable patterns.
Core Principles
Thin controllers — Controllers only receive requests, delegate to services, and return responses
Fat services — All business logic lives in service classes, never in controllers or models
Immutable DTOs — Data moves between layers via typed, readonly data transfer objects
Smart models — Models define relationships, scopes, casts, and accessors, but no business logic
Explicit authorization — Every action is authorized via policies, never inline in controllers
Side effects via events — Notifications, logging, webhooks are decoupled through events/listeners
Layer Architecture
Route (web.php / api.php)
│
▼
Controller ──────────────────────────────────────────────┐
│ │
├──▶ FormRequest (validation + authorization) │
│ └── rules(), authorize(), messages() │
│ │
├──▶ Service (business logic) │
│ ├── Uses Model for data access │
│ ├── Uses DTO for data transfer │
│ ├── Wraps operations in DB::transaction() │
│ └── Dispatches Events for side effects │
│ │
├──▶ Inertia::render() (for web responses) │
│ └── Passes props to React pages │
│ │
├──▶ Resource (for API responses) │
│ └── toArray() shapes JSON output │
│ │
└──▶ Policy (authorization) │
└── Checked via $this->authorize() │
│
Event ◀───────────────────────────────────────────────────┘
│
▼
Listener (side effects: notifications, logging, webhooks)
Request Lifecycle
Route matches the incoming HTTP request and dispatches to a Controller method
FormRequest validates and optionally authorizes before the controller body executes
Controller calls $this->authorize() for policy checks, then delegates to a Service
Service performs business logic, uses Model for persistence, creates/consumes DTOs
Service dispatches Events for side effects
Controller returns an Inertia::render() response (web) or a Resource (API)
Listeners handle events asynchronously (queued) or synchronously
Models are the data access layer. They define the shape of data, how it relates to other data, and how to query it. They must never contain business logic.
See references/dto-patterns.md for nested DTOs, enum-backed properties, validation within DTOs, spatie/laravel-data integration, and DTO vs Value Object vs FormRequest comparison.
Service Patterns
Services contain all business logic. They coordinate models, DTOs, transactions, and events.
Policies centralize all authorization logic. Every controller action should check a policy gate.
<?phpnamespaceApp\Policies;
useApp\Models\Order;
useApp\Models\User;
classOrderPolicy{
/**
* Run before any other checks.
* Returning null falls through to the specific method.
*/publicfunctionbefore(User $user, string$ability): ?bool{
if ($user->is_admin) {
returntrue;
}
returnnull; // fall through
}
/**
* Determine whether the user can view any orders.
*/publicfunctionviewAny(User $user): bool{
returntrue; // All authenticated users can see the list
}
/**
* Determine whether the user can view a specific order.
*/publicfunctionview(User $user, Order $order): bool{
->id === ->user_id;
}
{
;
}
{
->id === ->user_id
&& ->status->();
}
{
->id === ->user_id
&& ->status->();
}
{
->id === ->user_id;
}
{
;
}
}
See references/policy-patterns.md for team-scoped policies, role-based access with enums, Spatie Permission integration, and passing can() to Inertia frontend.
ServiceProvider Registration
The ServiceProvider wires everything together — bindings, policies, events, and routes.