Complete CRUD Example
v1.1.0This guide demonstrates the complete lifecycle of a generated domain, from running the Artisan command to exposing a production-ready REST API.
This is the recommended starting point for understanding how Laravel Domain Generator structures a new domain.
What you'll build
Running a single Artisan command generates a complete CRUD following DDD and Clean Architecture.
Included components:
- Model
- Migration
- Controller
- Form Requests
- DTO
- Service
- Repository
- Resource
- API Routes
Generation
Run:
php artisan make:domain UserThe generator creates every layer already connected.
Generated Structure
app/
├── Domain/
│ └── User/
│ ├── DTO/
│ ├── Repositories/
│ └── Service/
├── Http/
│ ├── Controllers/
│ ├── Requests/
│ └── Resources/
└── Models/Each file has a single responsibility.
Request Flow
Every request follows this pipeline.
This architecture keeps HTTP concerns separated from business rules.
Generated Controller
class UserController extends AbstractController
{
protected mixed $service;
protected ?string $requestValidate = UserRequest::class;
protected ?string $requestDto = UserDTO::class;
protected ?string $resource = UserResource::class;
}Notice that almost no CRUD logic is required.
Generated Service
public function create(UserDTO $dto)
{
return $this->repository->create(
$dto->toArray()
);
}Business rules belong here.
Generated Repository
public function model(): string
{
return User::class;
}Database operations stay isolated.
Create User
POST/api/usersRequest:
{
"nome": "John Doe",
"email": "john@example.com",
"password": "secret123"
}Response:
{
"type": "success",
"status": 201,
"data": {
"public_id": "01JXYZABCDEF123456789",
"nome": "John Doe",
"email": "john@example.com"
}
}List Users
GET/api/usersResponse:
{
"data": [],
"links": {},
"meta": {}
}Pagination works automatically.
Update User
PUT/api/users/{public_id}Request:
{
"nome": "John Updated"
}The update pipeline uses its own FormRequest and DTO.
Delete User
DELETE/api/users/{public_id}If SoftDeletes is enabled, the record is archived instead of permanently removed.
Best Practices
- Keep Controllers thin.
- Put business rules inside Services.
- Return Resources.
- Use public identifiers.
- Let Repositories own persistence.
The generated CRUD already follows the same layered architecture used throughout Laravel Domain Generator.