Tareas Comunes
Este documento describe tareas comunes del mundo real en Osumi Framework y la forma recomendada (canónica) de resolverlas.
Si existen varios enfoques posibles, solo se muestra la solución idiomática de Osumi Framework.
Todos los ejemplos asumen:
- PHP 8.3+
declare(strict_types=1);- Espacios de nombres adecuados
1. Crear un punto final JSON simple
Objetivo
Devolver JSON desde /api/ping.
Ruta
use Osumi\OsumiFramework\Routing\ORoute;
use Osumi\OsumiFramework\App\Module\Api\Ping\PingComponent;
ORoute::get('/api/ping', PingComponent::class);
Componente
class PingComponent extends OComponent {
public string $status = 'ok';
}
Plantilla (PingTemplate.json)
{
"status": "{{ status }}"
}
2. Recibir entrada mediante un DTO
Objetivo
Crear un usuario utilizando la entrada validada.
DTO
class CreateUserDTO extends ODTO {
#[ODTOField(required: true)]
public ?string $name = null;
#[ODTOField(required: true)]
public ?string $email = null;
}
Componente
class CreateUserComponent extends OComponent {
public string $status = 'ok';
public function run(CreateUserDTO $dto): void {
if (!$dto->isValid()) {
$this->status = 'error';
return;
}
$u = new User();
$u->name = $dto->name;
$u->email = $dto->email;
$u->save();
}
}
3. Proteger un endpoint con autenticación
Objetivo
Solo los usuarios autenticados pueden acceder a /api/profile.
Ruta
ORoute::get('/api/profile', ProfileComponent::class, [LoginFilter::class]);
Acceder a los datos del filtro
public function run(ORequest $req): void {
$login = $req->getFilter('Login');
$user_id = $login['id'];
}
4. Leer un parámetro de URL
Objetivo
Acceder a /user/:id.
Ruta
ORoute::get('/user/:id', UserComponent::class);
Componente
public function run(ORequest $req): void {
$id = $req->getParamInt('id');
$this->user = User::findOne(['id' => $id]);
}
5. Usar un servicio dentro de un componente
Objetivo
Extraer la lógica de negocio del componente.
Servicio
class UserService extends OService {
public function getAll(): array {
return User::where([]);
}
}
Componente
class UsersComponent extends OComponent {
private ?UserService $us = null;
public array $users = [];
public function __construct() {
parent::__construct();
$this->us = inject(UserService::class);
}
public function run(): void {
$this->users = $this->us->getAll();
}
}
6. Guardar o actualizar un modelo
Objetivo
Insertar o actualizar automáticamente usando save().
$user = new User();
$user->name = 'Alice';
$user->email = 'alice@mail.com';
$user->save(); // INSERTAR
$user = User::findOne(['id' => 1]);
$user->name = 'Updated Name';
$user->save(); // ACTUALIZAR
7. Devolver una lista de modelos (JSON)
Objetivo
Devolver usuarios usando un componente de modelo.
Dentro del componente
public ?UserListComponent $list = null;
public function run(): void {
$this->list = new UserListComponent();
$this->list->list = User::where([]);
}
Plantilla
{
"users": [
{{ list }}
]
}
8. Gestionar la subida de archivos
Objetivo
Subir un archivo de forma segura.
DTO
class UploadDTO extends ODTO {
#[ODTOField(required: true)]
public ?array $file = null;
public function __construct(ORequest $req) {
parent::__construct($req);
$this->file = $req->getFile('file');
}
}
Componente
public function run(UploadDTO $dto): void {
if (!$dto->isValid()) return;
$file = $dto->file;
$dest = $this->getConfig()->getDir('uploads') . basename($file['name']);
move_uploaded_file($file['tmp_name'], $dest);
}
9. Usar un diseño personalizado
Objetivo
Aplicar un diseño a un grupo de rutas.
ORoute::layout(MainLayoutComponent::class, function() {
ORoute::get('/home', HomeComponent::class);
});
O combinar prefijo + diseño:
ORoute::group('/admin', AdminLayoutComponent::class, function() {
ORoute::get('/dashboard', DashboardComponent::class);
});
Los diseños envuelven la salida del componente renderizado y reciben:
titlebody
10. Gestionar correctamente los errores de validación
Validación de DTO
if (!$dto->isValid()) {
$this->status = 'error';
$this->errors = $dto->getValidationErrors();
return;
}
Modelo no encontrado
$user = User::findOne(['id' => $id]);
if (is_null($user)) {
$this->status = 'error';
return;
}
Resumen
Estas recetas muestran la forma canónica de realizar tareas comunes en Osumi Framework:
- Usar DTO para la validación de entrada
- Usar filtros para la autenticación
- Usar servicios para la lógica de negocio
- Mantener componentes delgados
- Usar componentes de modelo para la representación JSON
- Aplicar diseños mediante enrutamiento
Siga estos patrones para lograr aplicaciones consistentes y predecibles.