Skip to content

Commit eb625fa

Browse files
[11.x] Add non-static JsonResource wrapping (#53543)
* Add support for non-static JsonResource wrapping * formatting --------- Co-authored-by: Taylor Otwell <taylor@laravel.com>
1 parent e7bdd64 commit eb625fa

File tree

3 files changed

+124
-2
lines changed

3 files changed

+124
-2
lines changed

src/Illuminate/Http/Resources/Json/JsonResource.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,13 @@ class JsonResource implements ArrayAccess, JsonSerializable, Responsable, UrlRou
4242
*/
4343
public $additional = [];
4444

45+
/**
46+
* The instance level wrapper configured for the resource.
47+
*
48+
* @var string|null
49+
*/
50+
public $wrapper = null;
51+
4552
/**
4653
* The "data" wrapper that should be applied.
4754
*
@@ -58,6 +65,8 @@ class JsonResource implements ArrayAccess, JsonSerializable, Responsable, UrlRou
5865
public function __construct($resource)
5966
{
6067
$this->resource = $resource;
68+
69+
$this->withWrapper(static::$wrap);
6170
}
6271

6372
/**
@@ -200,6 +209,29 @@ public function withResponse(Request $request, JsonResponse $response)
200209
//
201210
}
202211

212+
/**
213+
* Set the string that should wrap the outer-most resource array.
214+
*
215+
* @param string|null $value
216+
* @return $this
217+
*/
218+
public function withWrapper(?string $value)
219+
{
220+
$this->wrapper = $value;
221+
222+
return $this;
223+
}
224+
225+
/**
226+
* Disable wrapping of the outer-most resource array.
227+
*
228+
* @return $this
229+
*/
230+
public function withoutWrapper()
231+
{
232+
return $this->withWrapper(null);
233+
}
234+
203235
/**
204236
* Set the string that should wrap the outer-most resource array.
205237
*

src/Illuminate/Http/Resources/Json/ResourceResponse.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,11 +102,13 @@ protected function haveAdditionalInformationAndDataIsUnwrapped($data, $with, $ad
102102
/**
103103
* Get the default data wrapper for the resource.
104104
*
105-
* @return string
105+
* @return string|null
106106
*/
107107
protected function wrapper()
108108
{
109-
return get_class($this->resource)::$wrap;
109+
return $this->resource instanceof JsonResource
110+
? $this->resource->wrapper
111+
: get_class($this->resource)::$wrap;
110112
}
111113

112114
/**

tests/Integration/Http/ResourceTest.php

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,94 @@ public function testResourcesMayHaveNoWrap()
145145
]);
146146
}
147147

148+
public function testResourcesCanSetWithoutWrapper()
149+
{
150+
Route::get('/', function () {
151+
return (new PostResource(new Post([
152+
'id' => 5,
153+
'title' => 'Test Title',
154+
])))->withoutWrapper();
155+
});
156+
157+
$response = $this->withoutExceptionHandling()->get(
158+
'/', ['Accept' => 'application/json']
159+
);
160+
161+
$response->assertJson([
162+
'id' => 5,
163+
'title' => 'Test Title',
164+
]);
165+
}
166+
167+
public function testResourcesCanSetWithWrapper()
168+
{
169+
Route::get('/', function () {
170+
return (new PostResourceWithoutWrap(new Post([
171+
'id' => 5,
172+
'title' => 'Test Title',
173+
])))->withWrapper('postData');
174+
});
175+
176+
$response = $this->withoutExceptionHandling()->get(
177+
'/', ['Accept' => 'application/json']
178+
);
179+
180+
$response->assertJson([
181+
'postData' => [
182+
'id' => 5,
183+
'title' => 'Test Title',
184+
],
185+
]);
186+
}
187+
188+
public function testResourceCollectionCanSetWithWrapper()
189+
{
190+
Route::get('/', function () {
191+
return PostResourceWithoutWrap::collection([
192+
new Post([
193+
'id' => 5,
194+
'title' => 'Test Title',
195+
]),
196+
])->withWrapper('posts');
197+
});
198+
199+
$response = $this->withoutExceptionHandling()->get(
200+
'/', ['Accept' => 'application/json']
201+
);
202+
203+
$response->assertJson([
204+
'posts' => [
205+
[
206+
'id' => 5,
207+
'title' => 'Test Title',
208+
],
209+
],
210+
]);
211+
}
212+
213+
public function testResourceCollectionCanSetWithoutWrapper()
214+
{
215+
Route::get('/', function () {
216+
return PostResource::collection([
217+
new Post([
218+
'id' => 5,
219+
'title' => 'Test Title',
220+
]),
221+
])->withoutWrapper();
222+
});
223+
224+
$response = $this->withoutExceptionHandling()->get(
225+
'/', ['Accept' => 'application/json']
226+
);
227+
228+
$response->assertJson([
229+
[
230+
'id' => 5,
231+
'title' => 'Test Title',
232+
],
233+
]);
234+
}
235+
148236
public function testResourcesMayHaveOptionalValues()
149237
{
150238
Route::get('/', function () {

0 commit comments

Comments
 (0)