Automatic content negotiation. No magic. No bleeding into your code.
// Define a controller endpoint
class UserController extends Controller
{
public function __construct(private IUserService $users) {}
#[Post('/users')]
public function createUser(User $user): IResponse
{
$this->users->create($user);
return $this->created("/users/{$user->id}", $user);
}
#[Get('/users/:id')]
#[AuthorizeRoles('admin')]
public function getUserById(int $id): User
{
return $this->users->getById($id);
}
}
// Bind your dependency
$container->bindInstance(IUserService::class, new UserService());
// Run an integration test
$postResponse = $this->post('/users', new User('Dave'));
$user = $this->readResponseBodyAs(User::class, $postResponse);
$admin = (new PrincipalBuilder('example.com'))->withRoles('admin')
->build();
$getResponse = $this->actingAs($admin, fn () => $this->get("/users/$user->id"));
$this->assertParsedBodyEquals($user, $getResponse);
Install Aphiria
composer create-project aphiria/app --prefer-dist --stability dev