laravel / framework

The Laravel Framework.
https://laravel.com
MIT License
32.64k stars 11.04k forks source link

[11.x] Add non-static JsonResource wrapping #53543

Closed SanderMuller closed 1 day ago

SanderMuller commented 5 days ago

Overview

This PR addresses an issue with setting JSON wrappers on resource collections or other general-purpose JSON resource classes where adjusting the wrapper for an AnonymousResourceCollection or other generic resource class would affect all instances in the same request or following tests. This PR introduces instance-specific JSON wrapping to JsonResource through a new $wrapper property, along with withWrapper() and withoutWrapper() methods. This change allows developers to set a wrapper for individual resources without impacting others globally.

Example of the Issue

Currently, modifying the wrapper for a resource collection applies globally within the same request or test:

// Setting a wrapper for a resource collection
AnonymousResourceCollection::wrap('posts');

// This affects ALL instances of PostResource in the same request
$postsCollection = PostResource::collection($posts); // Wrapped with 'posts'
$booksCollection = BookResource::collection($books); // Also wrapped with 'posts'

With this PR, the wrapper can be set on a per-instance basis:

// Per-instance wrapper configuration
$postsCollection = PostResource::collection($posts)->withWrapper('posts');
$booksCollection = BookResource::collection($books)->withWrapper('books');

// Result: Different wrappers for different instances
// $postsCollection is wrapped with 'posts'
// $booksCollection is wrapped with 'books'

Benefits

Why This Change Doesn't Break Existing Features

The default behavior remains the same because the new instance-specific $wrapper property respects the global $wrap setting unless overridden. Existing resource configurations and behaviors are not altered unless explicitly changed.

How It Makes Building Web Applications Easier