Skip to content

Conversation

@Reinand
Copy link
Contributor

@Reinand Reinand commented Jan 15, 2026

🚀 Major Version Upgrade

This PR upgrades the package to Laravel 12 and PHP 8.5, and removes the deprecated registerData functionality.


⚠️ BREAKING CHANGES

1. Minimum Requirements

  • PHP: Now requires 8.5+ (was 8.2+)
  • Laravel: Now requires 12+ (was 8-11)

2. Removed Deprecated Functionality

  • ❌ Removed register() method
  • ❌ Removed registerData property
  • ✅ Must use method-based resource definitions

3. Method Visibility Change

  • toAttributes() is now public (was protected) for Laravel 12 compatibility

📝 Changes Made

Dependencies Updated

  • PHP: ^8.2^8.5
  • Laravel Framework: ^8.0 || ^9.0 || ^10.0 || ^11.0 || ^12.0^12.0
  • orchestra/testbench: ^7.22.0^10.0
  • phpunit/phpunit: ^9.6.3^11.0

Laravel 12 Compatibility Fixes

  1. Added resolveResourceData() override to prevent circular dependency between toArray() and toAttributes()
  2. Changed toAttributes() visibility from protected to public to match Laravel 12's base JsonResource class
  3. Added comprehensive documentation explaining why we override toAttributes() and how it differs from Laravel's implementation

Removed Deprecated Code

  • Removed private array $registerData property
  • Removed protected function register(): array method
  • Removed all fallbacks to registerData in getType(), toAttributes(), toRelationships(), toMeta(), toLinks()
  • Updated documentation to reflect method-based approach only

Test Resources Converted

All test resources converted from register() to method-based approach:

  • AccountResource.php
  • PostResource.php
  • CommentResource.php

🧪 Testing

All tests passing:

  • 49 tests
  • 85 assertions
  • ✅ Full compatibility with Laravel 12 and PHP 8.5

📖 Migration Guide for Users

Step 1: Update Requirements

composer require brainstud/json-api-resource:^5.0

Step 2: Change Method Visibility

Change all protected function toAttributes() to public function toAttributes():

// Before
protected function toAttributes(Request $request): array

// After
public function toAttributes(Request $request): array

Step 3: Convert register() to Method-Based Definitions

Before (deprecated):

protected function register(): array
{
    return [
        'id' => $this->resource->id,
        'type' => 'users',
        'attributes' => [
            'name' => $this->resource->name,
            'email' => $this->resource->email,
        ],
        'relationships' => [
            'posts' => ['posts', PostResourceCollection::class],
        ],
        'meta' => [
            'verified' => $this->resource->email_verified_at !== null,
        ],
        'links' => [
            'self' => route('users.show', $this->resource),
        ],
    ];
}

After (required):

protected string $type = 'users';

protected function toId(): string|int|null
{
    return $this->resource->id;
}

public function toAttributes(Request $request): array
{
    return [
        'name' => $this->resource->name,
        'email' => $this->resource->email,
    ];
}

protected function toRelationships(Request $request): array
{
    return [
        'posts' => ['posts', PostResourceCollection::class],
    ];
}

protected function toMeta(Request $request): array
{
    return [
        'verified' => $this->resource->email_verified_at !== null,
    ];
}

protected function toLinks(Request $request): array
{
    return [
        'self' => route('users.show', $this->resource),
    ];
}

🔍 Technical Details

Why Override toAttributes()?

Laravel 12's toAttributes() returns the full resource (same as toArray()), but JSON:API needs it to return only the attributes portion:

Laravel's behavior:

public function toAttributes(Request $request) {
    return $this->toArray($request);  // Full resource
}

JSON:API behavior:

public function toAttributes(Request $request): array {
    return [];  // Only attributes portion
}

This override is intentional and necessary to:

  1. Provide JSON:API-specific semantics
  2. Prevent circular dependency in the resource resolution chain
  3. Maintain separation between attributes, relationships, meta, and links

📌 Notes

  • Users on older PHP/Laravel versions should stay on v4.x
  • This is a major version bump due to breaking changes
  • All existing functionality preserved, just modernized for Laravel 12

BREAKING CHANGES:
- Require PHP 8.5+ (was 8.2+)
- Require Laravel 12+ (was 8-11)
- Remove deprecated register() method and registerData property
- Change toAttributes() visibility to public (Laravel 12 compatibility)
- Add resolveResourceData() override to prevent circular dependency

Changes:
- Updated composer.json dependencies for Laravel 12 and PHP 8.5
- Fixed Laravel 12 compatibility by overriding resolveResourceData()
- Changed toAttributes() from protected to public in all resources
- Removed registerData property and register() method from JsonApiResource
- Converted test resources from register() to method-based approach
- Updated documentation to reflect method-based definitions only

Migration Guide:
1. Upgrade to PHP 8.5+ and Laravel 12+
2. Change all 'protected function toAttributes()' to 'public function toAttributes()'
3. Convert any register() methods to toId(), toAttributes(), toRelationships(), toMeta(), toLinks()

All tests passing (49 tests, 85 assertions)
- Set php_version to 8.5 for composer and PHPUnit actions
- Update PHPUnit version from 9.6 to 11
@Reinand Reinand requested a review from brdv January 16, 2026 11:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants