# Restler 6: PHP REST APIs from reflected methods

> Restler is a PHP 8 framework that derives routes, parameter validation, response handling, and OpenAPI documentation from API classes. It suits teams that want a small API layer, but its reflection-driven design also reduces explicit control over routing.

**Luracast/Restler** — Zero-boilerplate REST API framework for PHP 8+. Auto-generates routes, docs, validation.

- Repository: https://github.com/Luracast/Restler
- Website: http://luracast.com/products/restler/
- Stars: 1,386 · Forks: 313
- Language: PHP
- License: not declared
- Published: 2026-10-16 · Updated: 2026-10-16 · Language: en
- Canonical page: https://hysenlabs.com/projects/luracast-restler

## What Restler Solves in a PHP API

Restler addresses the repetitive layer between a PHP application and an HTTP REST interface. Its README presents it as a way to write API logic as PHP methods while avoiding separate controller classes, route declarations, request DTOs, and configuration files for basic resources. That is most relevant to internal services, mobile backends, legacy integrations, and relatively direct resource APIs where method names and parameter types can form a useful contract.

The framework is aimed at PHP 8 projects. The README describes support for attributes, union types, named arguments, strict typing, PSR-7, and PSR-11. It also identifies JSON as the default response format and says OpenAPI 3 documentation can be generated from PHPDoc. These features reduce assembly work, but they do not remove the need to design authentication, persistence, domain errors, authorization, and deployment behavior. The project also mentions OAuth2 support and built-in rate limiting, although the README does not show their configuration.

Restler is not a general application framework in the broad sense. It focuses on exposing callable PHP classes through REST conventions. A database lookup, order creation operation, or CSV export still belongs in application code. The example Products class calls Database::findProduct($id), while the Orders example calls Order::create(...). Restler supplies the API-facing mechanism around those calls rather than implementing domain behavior.

## Reflection, Mapping, and Request Flow

The central mechanism is a PHP class registered through Routes::mapApiClasses(). In the shortest documented example, a Products class contains get(int $id), that class is mapped, and a Restler instance handles the request. Based on the repository layout and README example, Restler can infer a GET route for GET /products/123, validate the integer parameter, and return JSON by default.

Method signatures are therefore part of the interface contract. In the Hello example, sayHello(string $name = 'World') becomes the documented route GET /hello/sayHello/Restler when the parameter is supplied. A typed integer can reject non-integer input before the target method executes, according to the framework's automatic validation claim. Defaults also become visible in the generated contract, including getTime() with no required parameters.

Restler 6 also supports explicit attributes such as Get and Post. This gives a class more control when conventional class and method mapping is too opaque, as illustrated by #[Get('orders/{id}')] and #[Post('orders')]. The README does not explain precedence between inferred routes and attributed routes, so applications that depend on both mechanisms should inspect that behavior before adoption.

PHPDoc adds documentation metadata rather than replacing the PHP implementation. The Products example adds a description, @param, @return, and @throws annotation. The README states that this content feeds the OpenAPI 3 documentation and that the interactive explorer is available at /explorer. Returned arrays or domain objects are formatted by Restler, while XML, CSV, Excel, or HTML require formats to be configured through Routes::setOverridingResponseMediaTypes(). JSON needs no such extra setup.

## Installing Restler 6 and Calling the Hello API

The documented installation path is Composer. The project requires PHP 8 or newer, so confirm the target runtime before installing version 6. This command installs the framework within an existing Composer project:

```bash
composer require luracast/restler:^6.0
```

Next, create api/Hello.php with the two methods from the quick start. The string parameter has a default value, while getTime returns the current server time and the configured default timezone:

```php
<?php
class Hello {
    function sayHello(string $name = 'World'): string {
        return "Hello, $name!";
    }

    function getTime(): array {
        return ['time' => date('Y-m-d H:i:s'), 'timezone' => date_default_timezone_get()];
    }
}
```

The gateway in public/index.php loads Composer's autoloader, registers Hello, and hands request processing to Restler:

```php
<?php
require __DIR__ . '/../vendor/autoload.php';

Luracast\Restler\Routes::mapApiClasses([Hello::class]);
(new Luracast\Restler\Restler)->handle();
```

For the built-in PHP development server, run this from the project root:

```bash
php -S localhost:8080 -t public
```

A direct request should reach sayHello and use the supplied name:

```bash
curl http://localhost:8080/hello/sayHello/Restler
```

The documented response is the JSON string value "Hello, Restler!". This first call also demonstrates the compact route convention: there is no route file naming the class, method, or segment parameter. The server must be started with the working directory and path shown in the README for this example to resolve correctly.

## OpenAPI, Formats, and Streaming Export Boundaries

Restler derives its OpenAPI 3 documentation from the exposed PHP surface. Typed signatures supply parameter and return information, while PHPDoc can provide descriptions, product types, and failure annotations such as @throws 404. According to the README, an interactive API explorer is served at /explorer. The example uses findOrFail() to align a 404 annotation with domain behavior, but it does not establish a general rule for translating every exception into an HTTP status.

JSON is the default format. Additional formats are optional and require Routes::setOverridingResponseMediaTypes(), which means an endpoint suffix such as .xml is not proof that XML is already available in every installation. Once configured, a resource can be represented as JSON for one client and CSV or Excel for another. That is useful where consumers have incompatible format requirements.

For exports, the README documents a PHP Generator that yields user arrays. The stated mechanism is streaming, allowing large datasets to avoid collecting the entire result in memory before serialization. That depends on the selected CSV or Excel formatter consuming the generator incrementally. The README does not document buffer sizes, backpressure, spreadsheet cell limits, error handling after headers have been sent, or retry behavior. Large exports also place different demands on worker lifetime and memory than ordinary JSON endpoints.

The README says Restler can serve XML, CSV, Excel, and HTML, but it does not provide the configuration block for these formats. Treat those formats as documented capabilities with configuration work, not zero-configuration defaults.

## Swoole, ReactPHP, PHP-FPM, and AWS Lambda

Restler does not impose a single PHP execution model. The standard deployment path is Apache or Nginx with PHP-FPM. For production route caching, the README shows construction with productionMode set to true:

```php
$api = new Restler(productionMode: true);
```

For long-lived or asynchronous execution, the project documents Swoole, OpenSwoole, ReactPHP, Workerman, and AWS Lambda options. The Swoole path requires installing either extension and then launching the repository's dedicated entry point:

```bash
pecl install swoole
php public/index_swoole.php
```

The README also lists OpenSwoole as an alternative extension and a ReactPHP setup command:

```bash
composer react-server
```

For Lambda, it points to vendor/bin/bref deploy and public/index_lambda.php. These choices change process management, I/O behavior, extension requirements, and deployment assumptions. They are not interchangeable from the application's point of view even if Restler can expose the same mapped API classes.

The README states performance figures of 10 to 20 times PHP-FPM throughput and 15,000 or more requests per second on modest hardware. Those are repository claims, not independently verified here, and the README does not identify endpoint shape, payload size, database calls, concurrency, hardware, or latency percentiles. Such figures should not be used as an adoption threshold without a workload-specific evaluation.

## Explicit Routing Alternatives and Operational Trade-offs

A conventional REST layer usually keeps routing separate from domain services. Controllers receive framework-specific requests, dedicated validators define constraints, serializers shape responses, and a route table defines paths, methods, middleware, and names. That approach requires more files, but it gives reviewers an explicit place to inspect the HTTP contract. It also makes ambiguous mappings and cross-cutting middleware easier to identify.

Restler takes the opposite approach. The mapped PHP class is the contract, and method names, type declarations, attributes, and PHPDoc define how clients call it. This is less repetitive for simple APIs. It can also couple business code to HTTP exposure, however, because a method that returns a domain object may expose more structure than intended unless serialization and documentation behavior are checked.

Another limitation is discoverability. The README does not document route conflict handling, versioning policy, rollback behavior, or a complete list of defaults. It also does not explain how database transactions, authentication checks, authorization, or idempotency should be attached to exposed methods. Those concerns still require application design. Zero boilerplate does not mean zero API governance.

Restler 6 has recent release activity, with releases listed on 2026-08-22, 2026-08-19, and 2026-08-18. Its last push was on 2026-08-22, and the repository is not archived. The repository contains MIGRATION.md and CHANGELOG.md, which are the first files to inspect when moving between major versions. The Composer command requests ^6.0 while a 5.0.16 release is also listed, so upgrading from Restler 5 is not a routine assumption. The repository contains a license badge, but the README and repository metadata do not identify the license text here, so its exact permissions cannot be confirmed.

## Conclusion

Adopt Restler 6 when the API contract can be expressed cleanly through PHP methods, typed parameters, PHPDoc, or attributes. Do not adopt it if explicit route files, controllers, and custom request objects are organizational requirements. Verify route precedence, generated OpenAPI output, and the desired server mode before committing, because Restler delegates much of the contract to conventions rather than a separate routing configuration.

## FAQ

### How do I install Restler 6 for a PHP 8 project?

The README gives `composer require luracast/restler:^6.0` as the installation command. Restler is documented as requiring PHP 8 or newer.

### How do Restler 6 routes and validation work?

Restler uses PHP reflection over mapped classes, so a method such as `get(int $id)` can define a GET endpoint and validate `$id` as an integer. Attributes are available for explicit routes such as `#[Get('orders/{id}')]`.

### Does Restler generate OpenAPI documentation automatically?

The README states that Restler generates OpenAPI 3 documentation from exposed methods and PHPDoc comments. It also documents an interactive explorer at `/explorer`.

### Does Restler return XML and CSV without configuration?

JSON is the default, but the README says other formats are configured through `Routes::setOverridingResponseMediaTypes()`. XML, CSV, Excel, and HTML should therefore not be assumed to be enabled in a new installation.

### What license does Restler use?

The repository contains a license badge, but the README and repository metadata do not provide the license identifier or license text. Its exact licensing terms cannot be confirmed from these files.

## Sources

- [Issues](https://github.com/Luracast/Restler/issues)
- [Luracast/Restler on GitHub](https://github.com/Luracast/Restler)
- [Project website](http://luracast.com/products/restler/)
- [README](https://github.com/Luracast/Restler/blob/master/README.md)
- [Releases](https://github.com/Luracast/Restler/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/luracast-restler
