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.
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:
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.
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:
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.
# database/schema.yaml
models:
User:
id: int @primary
email: stringReturns a pure PHP 8.3 readonly class:
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.