Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Arch App Services Laravel Package

pekral/arch-app-services

A structured application-services layer for Laravel that keeps controllers thin by moving use-case logic into dedicated, testable service classes with a consistent architecture.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit

pekral/arch-app-services is an opinionated architecture toolkit for Laravel, not a runtime library. It supplies the scaffolding that enforces a specific layering convention — Actions as the unit of write-side behaviour, Data Validators as the boundary for input validation, and a Result pattern for outcomes — and then backs that convention with static analysis. This is a strong fit where the team has already bought into action-oriented Laravel (thin controllers, no business logic in models) and wants that convention made mechanically enforceable rather than documented in a wiki. It is a poor fit where the codebase is conventionally service/repository structured, since the PHPStan rules will flag existing code and the team will face a choice between mass refactoring and a large ignoreErrors baseline that defeats the purpose.

The 0.5.1 release does not add runtime capability; it refines the enforcement layer. Splitting a single combined rule into an Action rule and a Data Validator rule is architecturally correct — the two concerns have genuinely different namespaces and configurable scopes — and it lets a project adopt one convention without the other. The documentation additions (transactions, Result pattern, PHPStan rules) matter more than they look: an opinionated package lives or dies on how quickly a new engineer can infer the intended pattern, and previously the transaction/Result guidance was implicit.

Integration feasibility

The integration surface is narrow and low-risk: a handful of service container registrations, a neon config block for PHPStan, and package-level config supplying namespace prefixes. There is no database migration, no published config that must be reconciled, no middleware, no route registration. The main coupling is PHPStan — the package is only useful if static analysis runs in CI, so adoption requires PHPStan to be wired and gating in the pipeline. Without that, the package's value largely evaporates.

The 0.5.1 breaking change is contained by design: rule identifiers are unchanged, so existing ignoreErrors entries continue to work. Only projects that explicitly registered the removed combined class must edit their neon file, replacing one registration with two and supplying namespace arguments. That is a two-minute config edit per project, and the namespace arguments are an improvement in precision — the old rule presumably inferred scope, and the new rules state it.

Technical risk

  • Pre-1.0 semver. This is the dominant risk. The package went 0.5 → 0.5.1 and shipped a breaking change in a patch release. That is permitted pre-1.0 but means the team cannot rely on patch-level upgrades being safe. Pin to exact versions or a tight constraint and read release notes before every bump.
  • Enforcement-layer churn. Static analysis rules are the package's core value and also its most volatile surface. Rule splits, renames, and message changes will recur. Budget for a small amount of CI-config maintenance on each upgrade.
  • Convention lock-in. The Action/DataValidator namespaces and the Result pattern become load-bearing for the whole codebase's structure. Backing out later is expensive; the rules will have shaped dozens of classes by then.
  • Single-maintainer dependency. Changelog shows one author (@pekral). Bus factor of one on a package that gates CI is a genuine supply-chain and continuity consideration; consider vendoring or forking rights as a contingency.
  • Documentation as specification. The Result pattern and transaction guidance were only just documented. Early adopters may have implemented subtly different interpretations that the new docs and rules will now flag.

Key questions

  • Do we already run PHPStan in CI as a blocking gate, and at what level? The rules are only meaningful if the pipeline fails on violations.
  • Is our existing codebase action-oriented enough that adoption is a config change plus a baseline, rather than a refactor programme? What is the violation count against a dry run?
  • Which namespace convention do we use for actions and data validators, and does it match a single prefix each? The new rules take one actionNamespaces / dataValidatorNamespaces list each — mixed or nested conventions may need multiple registrations.
  • How many ignoreErrors entries do we currently carry for the old identifier, and do any of them mask violations we would now rather fix than suppress?
  • Who owns CI configuration, and what is the turnaround for a neon edit on the next breaking release?
  • Is the Result pattern a change to how new code returns outcomes, or a retrofit of existing return types? The documentation addition implies the former is expected but doesn't force the latter.

Integration Approach

Stack fit

Requires Laravel with PHPStan already in the toolchain and a codebase willing to adopt action-oriented structure. The package is additive — it registers rules and provides base classes/traits — so it does not conflict with existing service providers or with other Laravel architecture packages unless those also impose PHPStan rules over the same namespaces. Check for overlapping rules (e.g. another package enforcing controller or model purity) to avoid duplicate or contradictory errors on the same code.

Migration path

  1. Trial in a branch, not a feature branch — a config-only branch. Add the package, register the two current rules (not the removed combined one), point them at a narrow namespace first (one module or one bounded context). Run PHPStan and capture the violation count.
  2. Decide baseline vs. fix. For a greenfield module the count should be near zero. For legacy code, generate a baseline scoped to the package's identifiers rather than fixing everything at once, and track the baseline size as a burndown metric so it doesn't become permanent debt.
  3. Widen namespace scope incrementally — module by module — rather than pointing the rules at App\ on day one.
  4. Adopt the documentation conventions retroactively where cheap. The new Result pattern and transaction docs should become the reference for new Actions immediately; existing code follows as it's touched.
  5. Only then make the gate blocking. A blocking gate that fails on pre-existing debt gets disabled within a week.

If a project is on 0.5.x with the combined rule registered, the upgrade is mandatory-config: replace the single services entry with the two shown in the release notes, supplying the namespace arguments. Existing ignoreErrors identifiers carry over unchanged, so the baseline does not need regeneration — verify this with a CI run rather than trusting it.

Compatibility

No runtime or framework-version constraints were surfaced in this release; the change is confined to the PHPStan rule layer and docs. The one hard compatibility break is the removed class NoHttpExceptionsInActionsAndDataValidatorsRule — any neon file, shared config repo, or CI template referencing it by class name will fail to boot PHPStan. Grep for the class name across all repos and shared CI configurations, not just application code. Note that a neon file referencing a missing class typically produces a container-compilation error rather than a skipped rule, so this fails loudly — good, but it will block the pipeline until fixed.

Sequencing

Pin to 0.5.1 exactly rather than a caret range, given the pre-1.0 breaking-change-in-patch precedent. Sequence: config change → CI verification → merge. Then, separately and later, evaluate whether a constrained range is safe once the package reaches 1.0. Do not bundle this upgrade with other dependency work, since a failing PHPStan container is easy to misattribute to an unrelated change.

Operational Impact

Maintenance

Ongoing cost is low but non-zero: a handful of lines in a neon file, a config file, and periodic re-reading of release notes before upgrades. The real maintenance burden is not the package but the convention it enforces — every new engineer must learn Actions, Data Validators, and the Result pattern, and reviewers must hold the line. Budget onboarding documentation that points at the package's README, and treat the README as the source of truth rather than writing an internal variant that will drift.

Support

Single-maintainer upstream. For a package that gates CI, establish a contingency: either vendor a pinned copy, or confirm someone on the team can patch it locally if upstream goes quiet. Escalation path for rule false positives is ignoreErrors with an inline justification comment — require the comment, or the ignore list becomes unaccountable.

Scaling

Rules scale fine — PHPStan runtime grows with codebase size, not with rule count, and the split into two rules with explicit namespace arguments actually allows scoping to subsets. Configure PHPStan paths so analysis targets changed modules where possible. The organisational scaling risk is larger: as more teams and repos adopt this, the neon block and namespace conventions must be templated centrally. Maintain a shared CI config fragment so the next breaking release is a one-line change in one repo, not an audit across fifteen.

Failure modes

  • Silent non-enforcement. Rules registered against the wrong namespace prefix match nothing and pass clean. A green build then means nothing. Mitigate with a deliberate violation in a scratch branch to confirm the rules actually fire after registration.
  • Stale shared config. A CI template referencing the removed combined class breaks every repo at once on upgrade — loud, but wide-blast-radius. Grep before bumping.
  • Baseline ossification. ignoreErrors accumulates and the architecture drifts back toward the old conventions under the appearance of compliance. Track baseline size.
  • Pipeline-blocking upgrades. A patch bump that changes rule structure stops merges for every team simultaneously. Mitigate with exact pinning and a scheduled upgrade window rather than automatic dependency bumps.
  • Documentation drift. The just-added Result and transaction docs describe intent; if the rules lag the docs or vice versa, engineers get contradictory signals. When in doubt, the rule is the enforced truth.

Ramp-up

Half a day for an engineer already fluent in Laravel and PHPStan: read the README, wire the two rules, run against one module. One to two weeks before a team is genuinely productive in the idiom — the syntax is trivial, but knowing where an Action ends and a Data Validator begins, and when to return a Result versus throw, takes a few real features to internalise. The 0.5.1 documentation additions materially reduce this ramp-up and are the strongest argument for upgrading promptly rather than sitting on 0.5.0.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
encore2/laravel-admin2
cboxdk/laravel-console-kit
shapecode/doctrine-dbal-datetimeutc
gilads-otiannoh254/inertia-protocol
dakiquang/laravel-oauth-refresh-lock
woda/laravel-worktrees
dalefranks/ramasite
faghy/laracashbook
roundly-consulting/google-places-for-laravel
roundly-consulting/kubernetes-api-for-laravel
roundly-consulting/plausible-for-laravel
gvp/gvp-laravel-template
metasyncsite/laravel-metasync-client
roundly-consulting/onboarding-for-laravel
adachsoft/cli-process-tester
adachsoft/changelog-linter
adachsoft/collection
adachsoft/php-code-style
adachsoft/api-version-bundle
cgv/localized-resource