elshaden/apiato-livewire
elshadden/apiato-livewire integrates Livewire with Apiato, adding reactive, component-driven UI support to its modular Laravel architecture. Build dynamic interfaces with familiar Livewire syntax while keeping Apiato conventions.
Apiato is a Laravel starter/framework (Porto architecture) rather than a drop-in package, so "install" means scaffolding a project or pulling apiato/core plus its contracts into an existing app.
composer create-project apiato/apiato my-app — v11 tracks Laravel 11, so expect PHP 8.2+, the slim bootstrap/app.php application file, and no app/Http/Kernel.php.app/Containers/ — every feature lives in a Container; Ship/ holds shared infrastructure, App/ holds your domain.config/apiato.php — framework-wide switches (auth, requests, transformers, generator paths).app/Ship/Configs/ and each container's UI/API/Routes/ — routing is per-container, not global.php artisan apiato:container Blog, then wire up one endpoint end to end:
app/Containers/AppSection/Blog/UI/API/Routes/Request class for validation (apiato:request)Action (apiato:action) orchestrating one or more Tasks (apiato:task)Transformer (apiato:transformer) for the responsephp artisan route:list, php artisan apiato:list (shows containers/actions), and php artisan config:clear after adding containers — the framework caches container metadata.If you're upgrading rather than starting fresh, read the repo's UPGRADE guide first; the 5.0 notes are a single line ("Apiato V 11.") and tell you nothing about removals, so diff the skeleton against yours before trusting it.
Action → Task layering. Actions are the public use-case surface (one per endpoint/command); Tasks are reusable private units. Keep Actions thin — they should read as a sequence of Task calls plus a Transformer return. Anything you'd want to call from a Job, Command, and Controller belongs in a Task, not an Action.
Repository + Criteria for queries. Don't hand-write Eloquent in Actions. Put query logic behind a Repository and compose Criteria classes for filters/sorts/eager loads. This is the single biggest payoff of Apiato: your list endpoints become one-line criteria stacks and are testable without HTTP.
Requests own validation, Transformers own output. Controllers should barely exist — __invoke an Action with a validated Request. Use Transformer subclasses for every response so pagination, includes, and HATEOAS wrappers stay consistent across endpoints.
Per-container wiring. Migrations, seeders, factories, events, listeners, and tests all live inside the container. Register cross-container reactions via Events rather than direct calls; a Blog container firing PostCreated and an Audit container listening keeps boundaries honest.
Async work. Jobs and Commands call the same Actions. Because Actions take plain DTOs/Requests rather than HTTP objects, this is where the architecture earns its keep — resist the urge to pass Request instances into Jobs.
Testing. Container-scoped tests/Unit and tests/Api folders; use the generated test stubs so the directory conventions and namespace resolution stay correct. Prefer API functional tests that hit the route over unit-testing Actions in isolation — the request transformer layer is where most regressions hide.
Documentation. The built-in API doc generator reads @apiDefine/@apiPermission annotations and route metadata. Annotate as you go; retrofitting a dozen containers later is tedious.
app/Http/Controllers/FooController.php or a global routes/web.php "just this once" breaks the generator, the docs, and the container cache. Either adopt the structure or pick plain Laravel.app/Http/Kernel.php — middleware aliases, global middleware, and exception handling moved into bootstrap/app.php. If you're porting custom middleware from a v10 Apiato app, re-register it there; the old $routeMiddleware array is gone.php artisan optimize:clear before debugging anything else.api.php, web.php, private.php) in the container's UI/API/Routes or UI/WEB/Routes folder get loaded, with prefixing driven by the folder name. A misnamed file fails silently.\Exception from deep in a Task gives you unhelpful 500s — use the framework's typed exceptions or register a custom formatter in the Ship config.config/apiato.php, container-level Requests config); check them before assuming a bug.apiato:container, apiato:action, apiato:task, apiato:request, apiato:transformer, and apiato:migrate accept --section/--container flags that place files correctly. Hand-creating files and guessing the namespace is the most common source of "class not found" in new projects.Ship config overrides. Prefer extending Ship config over editing vendor files — v11 is a major bump and vendor edits won't survive the next jump.How can I help you explore Laravel packages today?