Core Concepts
Data Transfer Objects
Kipchak Framework: DTO Documentation
In Kipchak, Data Transfer Objects (DTOs) are used to decouple the external request and response data from your internal business logic. They serve as a structured contract that ensures data is validated and typed before it ever reaches your Models or Services, and that it is validated and typed correctly once again before it leaves the API (in order to ensure that you don't break any API contracts).
1. The Role of a DTO
Instead of passing the raw Slim Request object into your business logic, Kipchak extracts the data into a DTO. This provides several benefits:
- Type Safety: Ensures variables are the correct type (string, int, bool).
- Validation: Automatically rejects malformed requests.
- Auto-Completion: Provides IDE support when accessing request data in Services.
2. Directory Structure
DTOs are typically located within the versioned namespace of the module they belong to.
File Structure:
/src/DTOs
├── v1
│ ├── User
│ │ ├── CreateUserDTO.php
│ │ └── UpdateUserDTO.php
└── ...
3. Creating a DTO
A standard Kipchak DTO is a simple class that uses PHP properties to define the expected input. You can use PHP Attributes (like those from Symfony Validator or similar libraries integrated into the starter) to enforce rules.
Example (CreateUserDTO.php):
namespace Api\DTOs\v1\User;
class CreateUserDTO
{
public string $username;
public string $email;
public ?string $bio = null; // Optional field
public function __construct(array $data)
{
$this->username = $data['username'] ?? '';
$this->email = $data['email'] ?? '';
$this->bio = $data['bio'] ?? null;
}
}
4. Usage in a Controller
In a Kipchak Controller, the DTO is instantiated immediately after receiving the request. This ensures the rest of the method works with a clean object.
Example:
public function __invoke(Request $request, Response $response): Response
{
$params = (array)$request->getParsedBody();
// Instantiate the DTO
$dto = new CreateUserDTO($params);
// Pass the DTO to the Service/Model
$result = $this->userService->create($dto);
}
5. DTOs and OpenAPI
The DTO properties are often used by the framework to automatically generate the "Request Body" section of your Swagger documentation. By defining types in your DTO, your API documentation stays accurate without extra effort.
Best Practices Summary
| Practice | Description |
|---|---|
| Strict Typing | Always declare types (e.g., public string $name) for properties. |
| Immutability | Consider making properties readonly if using PHP 8.2+. |
| No Logic | DTOs should only store and validate data; they should not contain business logic. |
| Validation | Use the constructor or a dedicated validate() method to catch errors early. |