There is no license information available for the latest version (v2.6) of this package.

Installs: 1 003

Dependents: 0

Suggesters: 0

Security: 0

Stars: 0

Watchers: 0

Forks: 0

Open Issues: 0

pkg:composer/sabservis/api

v2.6 2026-02-17 20:49 UTC

This package is not auto-updated.

Last update: 2026-02-17 20:54:58 UTC


README

Moderní PHP REST API framework pro Nette s automatickou OpenAPI dokumentací.

PHP License CI Coverage Gate Tests Assertions PHPStan Code Style

Features

  • Deklarativní routing - Definuj endpointy pomocí PHP 8 atributů
  • OpenAPI 3.0 - Automatické generování dokumentace
  • Type-safe - Plná podpora typovaných parametrů, enumů, DTO
  • Middleware - Rozšiřitelný middleware pipeline (CORS, rate limiting, auth)
  • Validace - Vestavěná validace requestů s detailními chybami
  • File Uploads - Server-side MIME validace, filename sanitizace, symlink ochrana
  • Security - Rate limiting, request size limits, path traversal ochrana

Quick Start

composer require sabservis/api
# config.neon
extensions:
    api: Sabservis\Api\DI\ApiExtension

api:
    debug: %debugMode%
    maxRequestBodySize: 10485760  # 10MB limit (DoS ochrana)
    trustedProxies:               # Za reverse proxy (nginx, Cloudflare)
        - 10.0.0.0/8
        - 172.16.0.0/12
    router:
        basePath: /api
// www/index.php
Bootstrap::boot()
    ->createContainer()
    ->getByType(ApiApplication::class)
    ->run();
#[Tag(name: 'users')]
class UserController implements Controller
{
    #[Get(path: '/users/{id}')]
    public function get(int $id): UserDto
    {
        return $this->users->find($id);
    }

    #[Post(path: '/users')]
    #[RequestBody(ref: CreateUserDto::class)]
    public function create(ApiRequest $request): ApiResponse
    {
        $dto = $request->getEntity();
        return ApiResponse::created($this->users->create($dto));
    }
}

File Uploads

Bezpečné nahrávání souborů s automatickou MIME validací:

#[Post(path: '/documents')]
#[FileUpload(name: 'file', allowedTypes: ['application/pdf', 'image/jpeg', 'image/png'])]
public function upload(ApiRequest $request): ApiResponse
{
    $file = $request->getUploadedFile('file');

    // MIME type je automaticky validován pomocí finfo (magic bytes)
    // Klientský Content-Type header je ignorován (nelze spoofovat)

    // Bezpečný přesun - vytvoří adresář, sanitizuje název, nepřepíše existující
    $path = $file->moveToDirectory('/uploads');

    return ApiResponse::created(['filename' => basename($path)]);
}

Bezpečnostní funkce:

  • Server-side MIME detekce (finfo) - klient nemůže spoofovat typ souboru
  • Automatická filename sanitizace - ochrana proti path traversal (../)
  • Symlink ochrana - volitelné blokování symlinků
  • Validace allowedTypes na úrovni dispatcheru (415 Unsupported Media Type)
// Manuální validace v kontroleru
$file->getValidatedContentType();              // Server-side MIME type
$file->isAllowedType(['application/pdf']);     // true/false
$file->assertAllowedType(['application/pdf']); // throws exception
$file->getSanitizedName();                     // Bezpečný filename

// Bezpečný přesun souboru
$file->moveTo($path);                          // Nepřepíše existující (safe default)
$file->moveTo($path, overwrite: true);         // Explicitní přepsání
$file->moveToDirectory($dir);                  // Auto: vytvoří dir, sanitizuje název
$file->moveToDirectory($dir, 'custom.pdf');    // Vlastní název (sanitizovaný)

Validace request DTO

Framework automaticky validuje request DTO po deserializaci pomocí DataMapperEntityValidator. Na DTO properties používej validační atributy z knihovny pocta/data-mapper:

use Pocta\DataMapper\Validation\NotBlank;
use Pocta\DataMapper\Validation\Email;
use Pocta\DataMapper\Validation\Valid;

class CreateUserDto
{
    #[NotBlank]
    public string $name;

    #[Email]
    public string $email;

    #[Valid]
    public AddressDto $address;  // rekurzivní validace
}

Při odeslání nevalidních dat vrátí framework 422 s detailními chybami:

{
  "code": 422,
  "message": "Request body contains an error. See context for details.",
  "context": {
    "validation": {
      "name": ["This field is required."],
      "email": ["This value is not a valid email address."],
      "address.street": ["This field is required."]
    }
  }
}

Vypnutí validace

api:
    validator: null

Vlastní validátor

Implementuj EntityValidator interface a zaregistruj v konfiguraci:

class SymfonyEntityValidator implements EntityValidator
{
    public function validate(object $entity, array|string|null $validationGroups = null): void
    {
        // vlastní validační logika
        // při chybě throw new ValidationException()->withFields([...])
    }
}
api:
    validator: App\Api\Validator\SymfonyEntityValidator

Documentation

Téma Popis
Getting Started Instalace, konfigurace, první endpoint
Controllers & Routing Definice endpointů, HTTP metody, path parametry
Request & Response Práce s ApiRequest a ApiResponse
Parameters & Validation Query, path, header parametry, validace
OpenAPI Automatická dokumentace, Schema atributy
Middleware Vestavěné middleware, vlastní middleware
Security Rate limiting, file security, best practices
Testing ApiTestClient, testování controllerů

Requirements

  • PHP 8.1+
  • Nette DI 3.2+
  • Symfony Cache 6.4+

License

MIT