pekral / arch-app-services
Laravel package providing architectural abstractions for services, repositories and model managers
Package info
github.com/pekral/arch-app-services
Language:Shell
pkg:composer/pekral/arch-app-services
Requires
- php: ^8.4
- ext-simplexml: *
- baopham/dynamodb: ^7.1
- illuminate/contracts: ^12.0 || ^13.0
- illuminate/database: ^12.0 || ^13.0
- illuminate/pagination: ^12.0 || ^13.0
- illuminate/support: ^12.0 || ^13.0
- spatie/laravel-data: ^4.23.1
Requires (Dev)
- aws/aws-sdk-php: ^3.403.2
- ergebnis/composer-normalize: ^2.56.0
- iksaku/laravel-mass-update: ^1.0.9 || ^2.0
- larastan/larastan: ^3.14.0
- laravel/pint: ^1.32.2
- orchestra/testbench: ^10.11 || ^11.3
- pekral/cursor-rules: dev-master
- pekral/phpcs-rules: dev-master
- pekral/rector-rules: dev-master
- pestphp/pest: ^5.3.5
- pestphp/pest-plugin-type-coverage: ^5.1.0
- phpstan/extension-installer: ^1.4.3
- phpstan/phpstan: ^2.3.5
- phpstan/phpstan-deprecation-rules: ^2.0.5
- phpstan/phpstan-mockery: ^2.0
- phpstan/phpstan-phpunit: ^2.1.1
- rector/rector: ^2.8.4
- roave/security-advisories: dev-latest@dev
- squizlabs/php_codesniffer: >=4.0.4
- symfony/console: ^7.4.8 || ^8.1.11
Suggests
None
Provides
None
Conflicts
None
Replaces
None
- dev-master
- 0.5.2
- 0.5.1
- 0.5
- 0.4
- 0.3
- 0.2
- 0.1
- dev-docs/161-community-files
- dev-fix/dynamodb-local-isolation-and-test-tables
- dev-chore/install-ai-olympus
- dev-chore/laravel-13-support
- dev-composer-update-2026-01-25
- dev-composer-update-2026-02-01
- dev-composer-update-2026-02-08
- dev-composer-update-2026-01-11
- dev-composer-update-2026-01-18
- dev-composer-update-2025-12-21
- dev-composer-update-2025-12-28
- dev-composer-update-2026-01-04
- dev-composer-update-2025-11-30
- dev-composer-update-2025-12-07
- dev-composer-update-2025-12-14
- dev-composer-update-2025-11-23
- dev-petr-actions-middlewares
- dev-composer-update-2025-11-16
- dev-composer-update-2025-11-09
This package is auto-updated.
Last update: 2026-11-12 14:53:15 UTC
README
Arch App Services
Arch App Services gives Laravel applications single-purpose Actions, Repositories for reads, and Model Managers for writes. Model Services combine the read and write layers; Artisan generators and custom PHPStan rules help keep that structure consistent.
Note
The package is under active development and its API may change between releases. Review the changelog before upgrading.
Requirements
- PHP
^8.4with the SimpleXML extension. - Laravel 12 or 13 (
illuminate/*constraints:^12.0 || ^13.0).
Installation
composer require pekral/arch-app-services
Laravel discovers ArchServiceProvider automatically.
DynamoDB support is optional. Applications using the DynamoDB Repositories and Model Managers must also install the driver:
composer require "baopham/dynamodb:^7.1"
SQL-only applications do not need this dependency. See DynamoDB setup for models and configuration.
Configuration
No configuration is required: defaults for pagination, repository caching and transaction attempts load from config/arch.php. Publish the file to change them:
php artisan vendor:publish --tag="arch-config"
Publish the generator templates to customize generated classes:
php artisan vendor:publish --tag="arch-stubs"
Quick start
In a Laravel application with an existing App\Models\User model and migrated users table, generate its service stack:
php artisan make:arch-service "App\Models\User"
This creates UserModelService, UserRepository and UserModelManager in app/Services/User. The model must allow mass assignment of the fields you pass to create(); the example uses name, email and password.
Resolve the generated service through Laravel's container to write and read a user:
use App\Services\User\UserModelService; use Illuminate\Support\Facades\Hash; $users = app(UserModelService::class); $user = $users->create([ 'name' => 'Alex', 'email' => 'alex@example.com', 'password' => Hash::make('example-password'), ]); $found = $users->getOneByParams(['email' => 'alex@example.com']); // $found->id === $user->id
create() delegates to the Model Manager; getOneByParams() delegates to the Repository and throws ModelNotFoundException when no record matches. Use findOneByParams() for a nullable result.
Put an operation in an Action
Save this as app/Actions/User/UpdateUserName.php. It follows the package's final readonly Action convention and injects the generated service:
<?php namespace App\Actions\User; use App\Models\User; use App\Services\User\UserModelService; use Pekral\Arch\Action\ArchAction; final readonly class UpdateUserName implements ArchAction { public function __construct(private UserModelService $users) { } public function __invoke(string $name, User $user): void { $this->users->updateModel($user, ['name' => $name]); } }
Call the Action from a controller or another application entry point after validating and authorizing the request:
use App\Actions\User\UpdateUserName; $updateUserName = app(UpdateUserName::class); ($updateUserName)('Alex Morgan', $user);
This Action takes its inputs as __invoke() arguments. The optional ActionInvokeArgumentsRule PHPStan rule reports that style; see the rule summary before enabling it.
What it does
| Component | Responsibility |
|---|---|
| Actions & Model Services | Actions orchestrate an operation through __invoke(); Model Services combine reads and writes |
| Repositories & Model Managers | Query and paginate records; create, update, delete and process records in bulk, with SQL and DynamoDB implementations |
| Repository caching | Opt in to cached reads through CacheableRepository::cache(), with configurable TTL and explicit invalidation |
| Data objects & validation | Build DTOs on Spatie Laravel Data, validate input and transform data through pipelines |
| Transactions & Results | Wrap SQL writes with Transactional, #[InTransaction] helpers or nested savepoints; return explicit success/failure outcomes with Result |
| Architecture rules & generators | Generate Actions, service stacks, DTOs and validation rules; check layer boundaries, immutable dependencies and raw SQL bindings with PHPStan |
The #[InTransaction] attribute requires the TransactionAwareAction trait and an explicit call to executeWithTransactionAttribute() inside the Action. The attribute alone does not wrap execution. See the transaction example.
The package ships 24 PHPStan rules in the Pekral\Arch\PHPStan\Rules namespace. Installation alone does not enable them; register the rules you want in your PHPStan configuration. The rule summary lists each rule with a reported example.
Documentation
| Topic | Guide |
|---|---|
| Scaffolding | Artisan commands, options and custom stubs |
| Data access | Model Managers and bulk writes · Query Builder methods · Soft deletes |
| Cached reads | Caching, keys and invalidation |
| Input and transformation | DTOs and validation · Data Builder pipelines |
| DynamoDB | Models and setup |
| Architecture checks | PHPStan rule summary · Registration |
| Transactions | Atomic writes · Attribute helper · Nested savepoints |
| Expected failures | Result-based Action · Result API |
More working patterns are in examples/.
Testing
Repository development uses PHP 8.5, matching CI. The test suite uses SQLite and DynamoDB Local; composer test:coverage starts the local Docker Compose service through the bundled script. Coverage requires PCOV.
composer install composer test:coverage
| Command | Checks |
|---|---|
composer analyse |
PHPStan static analysis |
composer security-audit |
Dependencies against known security advisories |
composer check |
Composer normalization, PHPCS, Pint, Rector dry run, PHPStan, dependency audit and tests with a 100% coverage threshold |
Checkers runs on pushes and pull requests to master/main, and weekly.
Changelog
See CHANGELOG.md for release history and breaking changes.
Contributing
See CONTRIBUTING.md. Report bugs and request features through GitHub issues.
Report security vulnerabilities privately as described in the security policy. Everyone taking part is expected to follow the Code of Conduct.
License
MIT. See LICENSE.