Weave Code
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

Readonly Laravel Package

michaelachrisco/readonly

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture Fit

  • Use Case Alignment: The package excels in enforcing immutability for legacy systems, audit logs, or read-only data stores where write operations must be prohibited at the application layer (complementing DB-level permissions).
  • Laravel Integration: Leverages Eloquent’s trait system, requiring minimal architectural changes. Ideal for monolithic Laravel apps or microservices where certain models must be strictly read-only.
  • Separation of Concerns: Decouples business logic (e.g., "this model is never modified") from infrastructure (e.g., database permissions), reducing attack surface for accidental/malicious writes.

Integration Feasibility

  • Low Coupling: Single trait injection (use ReadOnlyTrait) with zero config. No middleware, service provider, or route changes required.
  • Backward Compatibility: Works with Laravel 5+ (tested up to 11.x via CI). No breaking changes to existing model behavior beyond write operations.
  • Testing Overhead: Minimal—existing unit tests for write operations will now fail explicitly (via ReadOnlyException), surfacing gaps in test coverage.

Technical Risk

  • False Sense of Security: Relying solely on this trait (without DB permissions) risks bypass via raw SQL or direct DB access. Mitigation: Pair with Laravel’s can() gates or database-level SELECT/UPDATE restrictions.
  • Edge Cases:
    • Mass Assignment: fill() or create() with arrays may not throw exceptions (unclear from docs). Action: Test or extend the trait to cover these.
    • Event Listeners: saved(), deleted() events may still fire post-exception. Action: Suppress events in the trait or document this behavior.
  • Performance Impact: Negligible—overhead is only added during write attempts.

Key Questions

  1. Scope of Protection: Should this apply to all models (via base model) or only specific ones (e.g., LegacyUser)?
  2. Exception Handling: How should downstream services (APIs, queues) handle ReadOnlyException? Retry? Log? Return user-friendly errors?
  3. Audit Trails: If writes are blocked, how will failed attempts be logged for compliance?
  4. Partial Writes: Are there use cases for conditional immutability (e.g., allow updates to updated_at but not email)?
  5. Testing Strategy: How will QA verify that read-only models cannot be modified (e.g., via API, CLI, or direct DB access)?

Integration Approach

Stack Fit

  • PHP/Laravel: Native support with zero framework modifications. Works alongside:
    • Eloquent: Core ORM integration.
    • API Resources: Read-only responses via readonly property in JsonResource.
    • Form Requests: Validate against write operations early (e.g., authorize() checks).
  • Non-Laravel: Not applicable—trait is Laravel-specific.

Migration Path

  1. Phase 1: Pilot
    • Apply ReadOnlyTrait to one legacy model (e.g., LegacyTransaction).
    • Update unit tests to expect ReadOnlyException for write operations.
    • Verify API endpoints return 403 (or custom error) for write attempts.
  2. Phase 2: Rollout
    • Extend to all read-only models via:
      • Base Model: Extend App\Models\Model with the trait (caution: affects all models).
      • Interface: Use ReadOnlyInterface (if adding custom logic).
    • Update CI/CD pipelines to scan for unintended write operations (e.g., save() calls on read-only models).
  3. Phase 3: Enforcement
    • Add database-level restrictions (e.g., REVOKE UPDATE on tables).
    • Integrate with Laravel’s policy system to gate write routes.

Compatibility

  • Laravel Versions: Tested on 5.5–11.x. Action: Verify compatibility with your Laravel version (e.g., 10.x+ may need adjustments for new Eloquent methods).
  • Third-Party Packages: Conflicts unlikely unless other packages monkey-patch Eloquent methods. Action: Check for overlapping traits (e.g., soft deletes).
  • Custom Model Logic: Overridden save()/update() methods may break. Action: Refactor to use the trait’s protected methods or extend the trait.

Sequencing

  1. Design: Document which models are read-only and why (e.g., "AuditLog", "LegacyData").
  2. Development:
    • Add trait to target models.
    • Update controllers/services to handle ReadOnlyException.
  3. Testing:
    • Negative tests for write operations.
    • Positive tests for read operations (e.g., find(), all()).
  4. Deployment:
    • Canary release to a non-production environment first.
    • Monitor for missed write attempts (e.g., via Sentry or custom logging).

Operational Impact

Maintenance

  • Low Effort: No ongoing maintenance beyond Laravel updates. Action: Watch for Eloquent method additions (e.g., replicate()) that may need trait updates.
  • Dependency Risk: Single maintainer (1 contributor). Mitigation: Fork if critical issues arise (e.g., security vulnerabilities).

Support

  • Debugging: ReadOnlyException provides clear feedback. Action: Log exceptions with context (e.g., user ID, endpoint) for auditing.
  • User Education: Developers must understand the trait’s scope (e.g., "This model is read-only—use LegacyDataService instead").
  • Documentation: Update API docs to mark read-only endpoints (e.g., @throws ReadOnlyException).

Scaling

  • Performance: No impact on read-heavy workloads. Write operations are blocked early (no DB calls).
  • Horizontal Scaling: Stateless—no changes needed for Laravel Horizon/queue workers.
  • Database: Reduces write load but may increase query complexity if joins are needed for read-only data.

Failure Modes

Failure Scenario Impact Mitigation
Trait bypassed via raw SQL Data corruption Enforce DB-level permissions.
Missing exception handling 500 errors in APIs Centralize exception handling (e.g., API middleware).
Overridden model methods Silent failures Static analysis (e.g., PHPStan) to detect save() calls.
Legacy code ignores the trait Inconsistent behavior Deprecate old code paths via deprecation warnings.

Ramp-Up

  • Developer Onboarding:
    • Training: 15-minute session on read-only patterns and exception handling.
    • Coding Guidelines: Add to style guide (e.g., "Tag read-only models with @readonly").
  • QA Process:
    • Add pre-commit hooks to detect save() calls on read-only models.
    • Automated tests for all write operations on read-only models.
  • Monitoring:
    • Alert on ReadOnlyException in production (e.g., "Someone tried to modify a read-only model").
    • Track false positives (e.g., legitimate attempts to update metadata like updated_at).
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.
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle