Osumi Framework
es en eu v9.8.1 GitHub

Common Tasks

This document describes common, real-world tasks in Osumi Framework and the recommended (canonical) way to solve them.

If multiple approaches are possible, only the idiomatic Osumi Framework solution is shown.

All examples assume:


1. Create a Simple JSON Endpoint

Goal

Return JSON from /api/ping.

Route

use Osumi\OsumiFramework\Routing\ORoute;
use Osumi\OsumiFramework\App\Module\Api\Ping\PingComponent;

ORoute::get('/api/ping', PingComponent::class);

Component

class PingComponent extends OComponent {
  public string $status = 'ok';
}

Template (PingTemplate.json)

{
	"status": "{{ status }}"
}

2. Receive Input Using a DTO

Goal

Create a user using validated input.

DTO

class CreateUserDTO extends ODTO {
  #[ODTOField(required: true)]
  public ?string $name = null;

  #[ODTOField(required: true)]
  public ?string $email = null;
}

Component

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. Protect an Endpoint with Authentication

Goal

Only authenticated users may access /api/profile.

Route

ORoute::get('/api/profile', ProfileComponent::class, [LoginFilter::class]);

Access Filter Data

public function run(ORequest $req): void {
  $login = $req->getFilter('Login');
  $user_id = $login['id'];
}

4. Read a URL Parameter

Goal

Access /user/:id.

Route

ORoute::get('/user/:id', UserComponent::class);

Component

public function run(ORequest $req): void {
  $id = $req->getParamInt('id');
  $this->user = User::findOne(['id' => $id]);
}

5. Use a Service Inside a Component

Goal

Move business logic out of the component.

Service

class UserService extends OService {
  public function getAll(): array {
    return User::where([]);
  }
}

Component

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. Save or Update a Model

Goal

Insert or update automatically using save().

$user = new User();
$user->name = 'Alice';
$user->email = 'alice@mail.com';
$user->save(); // INSERT

$user = User::findOne(['id' => 1]);
$user->name = 'Updated Name';
$user->save(); // UPDATE

7. Return a List of Models (JSON)

Goal

Return users using a Model Component.

Inside Component

public ?UserListComponent $list = null;

public function run(): void {
  $this->list = new UserListComponent();
  $this->list->list = User::where([]);
}

Template

{
  "users": [
    {{ list }}
  ]
}

8. Handle File Upload

Goal

Upload a file securely.

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');
  }
}

Component

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. Use a Custom Layout

Goal

Apply a layout to a group of routes.

ORoute::layout(MainLayoutComponent::class, function() {
  ORoute::get('/home', HomeComponent::class);
});

Or combine prefix + layout:

ORoute::group('/admin', AdminLayoutComponent::class, function() {
  ORoute::get('/dashboard', DashboardComponent::class);
});

Layouts wrap the rendered component output and receive:


10. Handle Validation Errors Properly

DTO Validation

if (!$dto->isValid()) {
  $this->status = 'error';
  $this->errors = $dto->getValidationErrors();
  return;
}

Model Not Found

$user = User::findOne(['id' => $id]);
if (is_null($user)) {
  $this->status = 'error';
  return;
}

Summary

These recipes show the canonical way to perform common tasks in Osumi Framework:

Follow these patterns for consistent, predictable applications.