Skip to content

FW Framework API Contracts

FW is strictly typed. Rather than forcing you to guess the structure of underlying objects, FW relies on PSR-compliant and strongly typed objects.

The Request Hierarchy

When an HTTP Request enters the FW ecosystem, the Swoole HTTP Request is immediately transformed into a Symfony HttpFoundation Request.

All generated route Handlers will receive this Request object as their primary input.

php
namespace Symfony\Component\HttpFoundation;

class Request
{
    public ParameterBag $query;    // ?foo=bar
    public InputBag $request;      // POST data
    public ServerBag $server;      // $_SERVER
    public FileBag $files;         // $_FILES
    public HeaderBag $headers;     // HTTP Headers
}

Retrieving Data

Inside your Handler:

php
public function __invoke(Request $request): JsonResponse
{
    // Getting a query string parameter:
    $page = $request->query->getInt('page', 1);

    // Getting JSON body data:
    $payload = json_decode($request->getContent(), true);
    
    // Getting an FW injected route parameter (e.g. /users/{id})
    $id = $request->attributes->get('id');
}

The Response Hierarchy

FW expects handlers to return a Symfony HttpFoundation Response object.

In most modern API applications, you will specifically return a JsonResponse.

php
namespace Symfony\Component\HttpFoundation;

class JsonResponse extends Response
{
    public function __construct(
        mixed $data = null, 
        int $status = 200, 
        array $headers = [], 
        bool $json = false
    );
}

Responding

Inside your Handler:

php
use Symfony\Component\HttpFoundation\JsonResponse;

public function __invoke(Request $request): JsonResponse
{
    $data = [
        'success' => true,
        'message' => 'User created.',
        'userId' => 123
    ];
    
    // Send a 201 Created response
    return new JsonResponse($data, 201);
}

Database DTOs (Models)

When you use the generated RepositoryInterface classes under the Modules/ syntax, they return Readonly Data Transfer Objects, not Active Record instances.

yaml
# database/schema.yaml
models:
  User:
    id: int @primary
    email: string

Returns a pure PHP 8.3 readonly class:

php
namespace Modules\User;

readonly class UserModel
{
    public function __construct(
        public int $id,
        public string $email
    ) {}
}

These DTOs contain zero methods, zero hidden lazy-loads, and exist strictly to provide deterministic type safety to the JsonResponse engine.

Engineered for Agents. Released under the MIT License.