Introduction
What it is
Laravel Rest Api turns your Eloquent models into a full API without one controller per use case. For each model, you write a resource that declares what the API exposes: its fields, its relations, its scopes, its actions and its rules. A thin controller binds the resource to a route name, and one call to Rest::resource() registers its endpoints.
namespace App\Rest\Resources;
use App\Models\Product;
use Lomkit\Rest\Fields\ID;
use Lomkit\Rest\Fields\Integer;
use Lomkit\Rest\Fields\Text;
use Lomkit\Rest\Relations\BelongsTo;
class ProductResource extends Resource
{
public static string $model = Product::class;
public function fields(): array
{
return [
ID::make('id'),
Text::make('name')->creationRules('required'),
Integer::make('price'),
];
}
public function relations(): array
{
return [
BelongsTo::make('category', CategoryResource::class),
];
}
}
use App\Rest\Controllers\ProductsController;
use Lomkit\Rest\Facades\Rest;
Rest::resource('products', ProductsController::class);
Clients can now search, filter, sort and paginate the products, include their category, create and update them in batches, and delete them, all inside the rules you declared.
The endpoints
Each registered resource answers on a fixed set of routes. The opt-in routes are added with withSoftDeletes() and withBatchProgress():
| Method | URI | Endpoint | Purpose |
|---|---|---|---|
GET | /api/products | details | Describe the resource for the current user |
POST | /api/products/search | search | Filter, sort, include, aggregate and paginate rows |
POST | /api/products/mutate | mutate | Create and update rows and their relations in one transaction |
POST | /api/products/actions/{action} | operate | Run an action that the resource declares |
POST | /api/products/metrics/{metric} | metric | Compute a metric that the resource declares |
DELETE | /api/products | destroy | Delete rows |
POST | /api/products/restore | restore | Restore soft-deleted rows, opt-in |
DELETE | /api/products/force | forceDestroy | Force delete rows, opt-in |
GET | /api/products/actions/{action}/batches/{batch} | batch | Read the progress of a batched action, opt-in |
See Resources for the registration options.
Why use it
- Declare, do not code. A column that a resource does not declare does not exist for clients. The same goes for relations, scopes, actions and instructions. Adding a column to a table never exposes it.
- One request, many rows. A search reads nested relations with their own filters and limits. A mutation creates a row, attaches its tags and updates its children in one transaction.
- Authorization built in. Every endpoint checks your Laravel policies:
viewAnyon each resource a request reaches, then each row it writes or deletes. A perimeter query decides which rows exist for each client. See Perimeter and Policies. - Typed and validated. Each field has a type that decides its filter operators, its validation and its OpenAPI schema. Every payload is validated in one pass, with exact error keys such as
search.filters.0.field. - Bounded. Request sizes, nesting depths and totals are limited by configuration, so one request cannot ask for unbounded work. See Limits.
- Documented. The package describes every endpoint in the OpenAPI document that Scramble serves. See OpenAPI.
How it fits Laravel
The package builds on what your application already has:
- Eloquent: resources read and write your models, their casts, their scopes and their relations.
- Policies: authorization goes through
Gateand your policy classes. See Policies. - Validation: field rules are Laravel rules, and errors come back as standard
422responses. See Validation. - Routing:
Rest::resource()registers plain Laravel routes that work with route groups, middleware,route:listandroute:cache. - Queues and events: actions can be queued or batched, and writes dispatch Laravel events. See Actions and Events and hooks.
- Laravel Scout: a resource can run its text search on a Scout search engine. See Search engines.
- Laravel Precognition: forms can validate a payload before they send it. See Precognition.
Version 3
Version 3.0 types every declaration: fields, inputs and pivot fields are objects with a type, and the search, mutate and action payloads are validated against them. If you come from 2.x, read the Upgrade guide.
Meet Lomkit
Lomkit is an organization dedicated to the Laravel community. We offer a collection of open source packages for developers, and we keep them up to date with the latest practices of the framework.
Community contributions are welcome. Explore our packages on GitHub, open an issue or send a pull request.
Next steps
- Install the package.
- Expose your first models with
rest:quick-start.