Laravel Packages

Laravel Rest Api 3.0: Typed Fields, Metrics, and OpenAPI Docs

Published
Laravel Rest Api 3.0: Typed Fields, Metrics, and OpenAPI Docs image

Gautier Deleglise just released Laravel Rest Api 3.0, a rebuild of the package that turns your Eloquent models into a REST API from a single resource class. We first covered it when it launched in 2023 and again when it added Laravel Scout support. Version 3.0 keeps the same idea and replaces most of what sits underneath it.

Some of the highlights include:

  • Typed fields that drive filters, validation, response values, and the API docs
  • OpenAPI documentation through Scramble
  • Metric endpoints for counts, trends, partitions, progress, and tables
  • Confirmations for actions and bulk writes, using a 428 response and a signed token

Typed Fields

In 2.x, a resource listed column names. In 3.0, a resource declares typed fields with Text, Integer, Number, Date, Enum, Json, and more:

public function fields(): array
{
    return [
        ID::make('id'),
        Text::make('title')->rules('max:80')->creationRules('required'),
        Integer::make('seats')->rules('min:0'),
        Enum::make('status', ShowStatus::class)->offered([ShowStatus::Planned, ShowStatus::OnSale]),
        Date::make('starts_on')->creationRules('required'),
    ];
}

The package uses that one declaration for the rest of the API:

  • Filters only accept operators that fit the field's type. Anything else returns a 422.
  • Writes are validated against the field's rules, and errors point at the exact key that failed, such as mutate.0.attributes.seats.
  • Responses return values in their type, so numbers come back as numbers and an empty JSON field comes back as {}.
  • Enum::offered() limits which cases a client can write. In the example above, a withdrawn status is still readable and filterable on old rows, but nobody can set it again.

OpenAPI Docs Through Scramble

The built-in documentation generator is gone. Version 3.0 integrates with Scramble instead. Once you install Scramble, /docs/api documents every endpoint of every resource, with a typed body per resource, the rules for each field, request examples, and error responses.

The package's own test suite sends those request examples to the API and validates each response against the generated document. If the docs and the API ever disagree, a test fails.

Metrics

Metrics are new in 3.0. You declare a metric on a resource, and it gets its own route with no controller code. Here is a partition that counts shows by status:

class ShowsByStatus extends Partition
{
    public function calculate(Builder $query): PartitionResult
    {
        return $this->count($query, 'status');
    }
}

The endpoint returns each group with its count:

{"data": {"type": "partition", "parts": [{"key": "planned", "label": "planned", "value": 2}, {"key": "sold_out", "label": "sold_out", "value": 1}], "other": null}}

The Value, Trend, Partition, Progress, and Table metric types cover counts, sums, averages, medians, and percentiles. They also support date ranges, time zones, a comparison with the previous period, and a result cache. A metric only counts the rows the current user is allowed to see, and the client can narrow it further with the same filters it uses for search.

Confirmations

An action, a mutate, a destroy, a restore, or a force destroy can now ask the user to confirm before it runs. This works well for bulk cancellations and deletions:

public function destroyConfirmation(Collection $models): ?Confirmation
{
    return Confirmation::make("Delete {$models->count()} shows and their tickets?");
}

The endpoint responds with a 428 status, your message, and a signed token. When the client sends the same request back with that token, it runs. There is no session involved and no extra endpoint to call.

Other Changes

  • Policies run on every resource a request reaches and on every row it writes, before the first write happens. perimeterQuery() scopes each resource to a tenant or team at every level of a search.
  • A single write can create, update, attach, sync, and delete child rows in one transaction. A response block returns the written rows, and resources marked versioned() return a 409 when a row changed after the client read it.
  • Actions can run in one transaction per run, per chunk, or per row, with queued chunks and batches that report progress.
  • Rest::search() replays a saved search outside of HTTP, so a job or an export goes through the same rules and policies as the API.
  • Text search works with LIKE, MySQL, MariaDB, or PostgreSQL full-text indexes, or Meilisearch, Typesense, and Algolia through Scout.
  • Every client-facing message ships in English and French and follows the request locale.
  • php artisan rest:quick-start reads your tables and generates resources, controllers, starter policies, and routes. php artisan rest:check catches a missing policy or perimeter in CI.
  • The package ships a Laravel Boost skill, so your AI assistant writes resources the way the package expects.

Upgrade Notes

Laravel Rest Api 3.0 requires PHP 8.3+ and Laravel 13.30+. Applications on Laravel 12 should stay on 2.x.

composer require lomkit/laravel-rest-api:^3.0

Version 3.0 has breaking changes across the package, and the upgrade guide walks through each one, area by area.

References

Eric L. Barnes photo

Eric is the creator of Laravel News and has been covering Laravel since 2012.

Sponsored

laravelcloud logo
Laravel Cloud

Easily create and manage your servers and deploy your Laravel applications in seconds.

Visit Laravel Cloud

The latest

View all →
Search Polymorphic Relations and Filament Tables With Laravel Searchable image

Search Polymorphic Relations and Filament Tables With Laravel Searchable

Read article
Real-Time Inertia Props With Laravel Reverb image

Real-Time Inertia Props With Laravel Reverb

Read article
PhpStorm 2026.3 Adds an Agent Workspace and PHP 8.6 Support image

PhpStorm 2026.3 Adds an Agent Workspace and PHP 8.6 Support

Read article
Insert Middleware Before or After Existing Laravel Middleware image

Insert Middleware Before or After Existing Laravel Middleware

Read article
Laravel Herd 2: Coding Agents, Workspaces, and Cloud Deploys image

Laravel Herd 2: Coding Agents, Workspaces, and Cloud Deploys

Read article
Strict Request Input Casting in Laravel image

Strict Request Input Casting in Laravel

Read article