Introduction
Roma is a Request/Response Object MApper for Laravel. It maps all aspects of an
Illuminate\Http\Request — headers, the query string, the body, files, cookies, route
parameters, and convenience methods like $request->ajax() — into a fully type-safe,
validated plain PHP object. The goal: when you use a Roma request, you never touch the
underlying Laravel request directly.
On the response side, Roma converts a plain object (recursively) into the JSON body of a
JsonResponse, with properties that can instead drive the status code or headers.
And with one command, Roma generates TypeScript definitions for both requests and responses — one source of truth shared by your backend and frontend.
When to reach for Roma
When an endpoint needs typed, validated input from anywhere in the request, reach for a
Roma request object instead of a hand-rolled FormRequest plus a manual array-to-DTO
step. You declare typed properties; Roma populates and validates them. It is a type-safe
FormRequest and DTO in one.
Mark the class #[Request] and type-hint it in your controller — Roma maps and validates
it before your action runs:
use BYanelli\Roma\Request\Attributes\Rule;
use BYanelli\Roma\Request\ContextualBinding\Request;
#[Request]
readonly class CreateContactRequest {
public function __construct(
#[Rule('max:255')]
public string $name,
#[Rule(['email', 'unique:contacts', 'max:255'])]
public string $email,
) {}
}
class CreateContactController {
public function __invoke(CreateContactRequest $request) {
Contact::create([
'name' => $request->name,
'email' => $request->email,
]);
}
}
The rest of these docs walk through defining requests, the sources a property can bind to, headers and request metadata, nested objects, response objects, and TypeScript generation.
These docs as Markdown
Prefer plain text? The entire documentation is served as a single Markdown file at yanelli.dev/docs/roma.md — hand it to an AI coding assistant, or just read everything in one place. Each version has its own too (e.g. /docs/roma/v1.md).