tomatophp/filament-api
TomatoPHP Filament API adds RESTful endpoints to Filament resources, letting you expose CRUD operations, filters, and relationships via Laravel Sanctum authentication. Generate and manage model APIs directly from your admin panel.
Build vs. buy on the CRUD surface. The real question this package answers is not "do we need an API" but "do we keep spending a sprint of boilerplate per entity we already manage in Filament." Hand-written controllers, form requests, API resources, filtering, and pagination for conventional CRUD are pure tax. Generating them from the resource definition converts that line item into a configuration change plus code review, and redirects engineering capacity toward domain logic, authorization semantics, and the non-CRUD work that actually differentiates the product.
Roadmap sequencing and time-to-integration. When a mobile app, partner portal, internal automation, or data pipeline is on the roadmap and consumes the same models the admin panel already owns, generating the API from the resource lets the integration ship alongside the UI instead of as a phase behind it. For integration-gated features — UI is done, nothing can launch until endpoints exist — this turns a sequential dependency into a parallel workstream and can pull a release forward by weeks. That is the single strongest PM argument for adoption.
One definition, two surfaces. Filament resources already encode field lists, validation rules, relationships, and table filters. Deriving the API from that resource means the panel and the API share a contract by construction, which structurally eliminates the "admin accepts a value the API rejects" defect class and removes the drift of maintaining two validation layers. This is a durable quality and support-cost benefit, not merely a velocity one — and it survives even if the speed gain is smaller than advertised.
MVP and internal-tool scoping. Best suited to surfaces where speed-to-endpoint beats contract polish: back-office automation, ops tooling, internal dashboards, low-traffic partner endpoints, demo and proof-of-concept work that would otherwise be hand-rolled or skipped entirely. It lets a small team without an API specialist ship a working integration.
Estimation, staffing, and a named risk. Adoption is a legitimate reason not to allocate a sprint of serialization plumbing, and it should be recorded in planning as an explicit bet: the resource definition becomes the API's source of truth. That is fast and correct while the two genuinely coincide, and it becomes a constraint the moment a consumer needs a contract that diverges from the admin UI. PMs should log that divergence point as a monitored roadmap risk with a documented exit, not absorb it as a surprise later.
Scope control as a product lever. Per-resource opt-in is the mechanism that makes adoption incremental. You expose one boring resource, prove the mechanism, and then decide the order in which the rest follow. That gives a PM a controllable rollout surface instead of a binary "adopt the package" decision — each annotated resource is a contract you consciously choose to own.
Consider it when:
Look elsewhere — or budget a fork-and-own commitment — when:
The go/no-go test set. Four tests constitute the adoption decision: (1) policy enforcement on a generated route returns 403 for an unauthorised user, (2) tenant A cannot read tenant B's row, (3) a relationship write behaves as expected, (4) an invalid payload returns a sane 422 with field errors. Anything you cannot demonstrate with a passing test, you do not have.
For executives — the one-paragraph version: Our admin panel already defines every field, validation rule, and relationship for the models we manage. This package lets us derive a REST API from that same definition, so we can ship mobile, partner, and internal integrations without writing a sprint of boilerplate per entity — and without maintaining two validation layers that quietly drift apart. The immediate business value is calendar time: work that was sequenced behind the UI can now run in parallel with it. The cost is a coupling we must manage: the admin resource becomes the API's source of truth, which is an asset while the two coincide and a constraint when they don't. We propose adopting it incrementally on internal, low-blast-radius surfaces, with a documented exit and an endpoint test suite that makes a future fork safe.
For engineering — the framing: Treat the resource as the single source of truth, but read it end to end before you trust it. Confirm the contract/trait name against src/Contracts rather than a blog post. Read config/filament-api.php first — prefix, middleware, guard — and set the prefix to api/v1 on day one. Read the generated controller once, all the way through, to verify how it resolves the model, applies filters, and respects $fillable/$guarded. Own the query: getEloquentQuery() is where eager loading and tenant scoping live. Wire authorization yourself and prove it with a test rather than assuming panel policies apply. Add throttle:api and CORS paths; nothing here implies they're configured. Pin the package and Filament together with an explicit upper bound — a Filament major upgrade is effectively an upgrade to this package's assumptions. And keep a hand-written seam from day one: the moment a consumer needs a computed field, a bulk operation, or a workflow endpoint, hand-write it under a distinct route file or controller namespace, so the codebase has two clearly labelled sets of routes rather than a split-brain API with no provenance.
The honest risk statement to put in the decision record: This is a thin layer over our own Eloquent models, maintained by a single author with low adoption and no dependents. We are betting that internal CRUD surfaces and a first-party client on a bounded domain are worth the coupling — and we are de-risking that bet three ways: per-resource opt-in rather than a sweep of the panel, one feature test per endpoint per resource using Sanctum::actingAs, and a named owner with pinned versions if we ever need to fork. If a consumer later demands a contract that diverges from the admin UI, that is the trigger to re-evaluate — not a surprise to absorb.
How can I help you explore Laravel packages today?