Skip to content

Commit 3134ca2

Browse files
Allow auto parsing the fieldsets (#261)
* fix: wrong `return` annotation * fix: wrong return type annotation * feat: auto-parse fieldsets * Fix styling --------- Co-authored-by: Mohammad-Alavi <Mohammad-Alavi@users.noreply.github.com>
1 parent ef2ab3a commit 3134ca2

File tree

5 files changed

+168
-5
lines changed

5 files changed

+168
-5
lines changed

README.md

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ This is the contents of the published file:
9696

9797
```php
9898
return [
99-
/*
99+
/*
100100
* The default serializer to be used when performing a transformation. It
101101
* may be left empty to use Fractal's default one. This can either be a
102102
* string or a League\Fractal\Serializer\SerializerAbstract subclass.
@@ -105,11 +105,12 @@ return [
105105

106106
/* The default paginator to be used when performing a transformation. It
107107
* may be left empty to use Fractal's default one. This can either be a
108-
* string or a League\Fractal\Paginator\PaginatorInterface subclass.*/
108+
* string or a League\Fractal\Paginator\PaginatorInterface subclass.
109+
*/
109110
'default_paginator' => '',
110111

111112
/*
112-
* League\Fractal\Serializer\JsonApiSerializer will use this value to
113+
* League\Fractal\Serializer\JsonApiSerializer will use this value
113114
* as a prefix for generated links. Set to `null` to disable this.
114115
*/
115116
'base_url' => null,
@@ -133,12 +134,12 @@ return [
133134
*/
134135
'request_key' => 'include',
135136
],
136-
137+
137138
'auto_excludes' => [
138139

139140
/*
140141
* If enabled Fractal will automatically add the excludes who's
141-
* names are present in the `include` request parameter.
142+
* names are present in the `exclude` request parameter.
142143
*/
143144
'enabled' => true,
144145

@@ -147,6 +148,21 @@ return [
147148
*/
148149
'request_key' => 'exclude',
149150
],
151+
152+
'auto_fieldsets' => [
153+
154+
/*
155+
* If enabled Fractal will automatically add the fieldsets who's
156+
* names are present in the `fields` request parameter.
157+
*/
158+
'enabled' => true,
159+
160+
/*
161+
* The name of key in the request, where we should look for the fieldsets to parse.
162+
*/
163+
'request_key' => 'fields',
164+
],
165+
];
150166
```
151167

152168
## Usage

config/fractal.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,20 @@
5353
*/
5454
'request_key' => 'exclude',
5555
],
56+
57+
'auto_fieldsets' => [
58+
59+
/*
60+
* If enabled Fractal will automatically add the fieldsets who's
61+
* names are present in the `fields` request parameter.
62+
*
63+
* NOTE: This feature does not work if the "resource name" is not set.
64+
*/
65+
'enabled' => true,
66+
67+
/*
68+
* The name of key in the request, where we should look for the fieldsets to parse.
69+
*/
70+
'request_key' => 'fields',
71+
],
5672
];

src/Fractal.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,14 @@ public static function create($data = null, $transformer = null, $serializer = n
5151
}
5252
}
5353

54+
if (config('fractal.auto_fieldsets.enabled')) {
55+
$requestKey = config('fractal.auto_fieldsets.request_key');
56+
57+
if ($fieldsets = app('request')->get($requestKey)) {
58+
$fractal->parseFieldsets($fieldsets);
59+
}
60+
}
61+
5462
if (empty($serializer)) {
5563
$serializer = config('fractal.default_serializer');
5664
}

tests/AutoFieldsetsTest.php

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
<?php
2+
3+
use Illuminate\Testing\Fluent\AssertableJson;
4+
5+
it('returns only requested fields', function ($fields, $expectedMissing) {
6+
$response = $this->call('GET', '/auto-fieldsets-with-resource-name', [
7+
'fields' => [
8+
'books' => $fields,
9+
],
10+
'include' => 'characters,publisher',
11+
]);
12+
13+
$response->assertOk();
14+
$response->assertJson(
15+
fn (AssertableJson $json) => $json->has(
16+
'data',
17+
2,
18+
fn (AssertableJson $json) => $json->hasAll($fields)
19+
->missing($expectedMissing),
20+
),
21+
);
22+
})->with([
23+
['author', 'id'],
24+
['id', 'author'],
25+
[['author', 'id'], 'publisher'],
26+
[['id', 'author', 'publisher'], 'characters'],
27+
]);
28+
29+
it('doesnt work if "resource name" is not set', function ($fields) {
30+
$response = $this->call('GET', '/auto-fieldsets-without-resource-name', [
31+
'fields' => [
32+
'books' => $fields,
33+
],
34+
'include' => 'characters,publisher',
35+
]);
36+
37+
$response->assertOk();
38+
$response->assertJson(
39+
fn (AssertableJson $json) => $json->has(
40+
'data',
41+
2,
42+
fn (AssertableJson $json) => $json->hasAll(['id', 'author', 'characters', 'publisher'])
43+
),
44+
);
45+
})->with([
46+
['author', 'id'],
47+
['id', 'author'],
48+
[['author', 'id']],
49+
[['id', 'author', 'publisher']],
50+
]);
51+
52+
it('all fields are present when parameter is not passed', function () {
53+
$response = $this->call('GET', '/auto-fieldsets-with-resource-name', [
54+
'include' => 'characters',
55+
]);
56+
57+
$response->assertOk();
58+
$response->assertJson(
59+
fn (AssertableJson $json) => $json->has(
60+
'data',
61+
2,
62+
fn (AssertableJson $json) => $json->hasAll(['id', 'author', 'characters'])
63+
->missing('publisher'),
64+
),
65+
);
66+
});
67+
68+
it('can be disabled via config', function () {
69+
config()->set('fractal.auto_fieldsets.enabled', false);
70+
71+
$response = $this->call('GET', '/auto-fieldsets-with-resource-name', [
72+
'fields' => [
73+
'books' => ['author', 'id'],
74+
],
75+
'include' => 'characters,publisher',
76+
]);
77+
78+
$response->assertOk();
79+
$response->assertJson(
80+
fn (AssertableJson $json) => $json->has(
81+
'data',
82+
2,
83+
fn (AssertableJson $json) => $json->hasAll(['id', 'author', 'characters', 'publisher'])
84+
),
85+
);
86+
});
87+
88+
it('uses the configured request key', function () {
89+
config()->set('fractal.auto_fieldsets.request_key', 'other_fields');
90+
$response = $this->call('GET', '/auto-fieldsets-with-resource-name', [
91+
'fields' => [
92+
'books' => 'author',
93+
],
94+
'other_fields' => [
95+
'books' => 'id',
96+
],
97+
]);
98+
99+
$response->assertOk();
100+
$response->assertJson(
101+
fn (AssertableJson $json) => $json->has(
102+
'data',
103+
2,
104+
fn (AssertableJson $json) => $json->has('id')
105+
->missing('author')
106+
),
107+
);
108+
});

tests/TestCase.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,5 +82,20 @@ protected function setupRoutes()
8282
->transformWith(TestTransformer::class)
8383
->toArray();
8484
});
85+
86+
Route::get('auto-fieldsets-with-resource-name', function () {
87+
return fractal()
88+
->withResourceName('books')
89+
->collection($this->testBooks)
90+
->transformWith(TestTransformer::class)
91+
->toArray();
92+
});
93+
94+
Route::get('auto-fieldsets-without-resource-name', function () {
95+
return fractal()
96+
->collection($this->testBooks)
97+
->transformWith(TestTransformer::class)
98+
->toArray();
99+
});
85100
}
86101
}

0 commit comments

Comments
 (0)