New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Avoid data
in included elements?
#90
Comments
You can use Serializers to achieve this |
Thanks, that will do. |
I've written a custom serializer to try to solve my problem, and if I understand correctly, I would need to implement this behaviour in the
Changes to the |
Any ideas, anyone? |
+1 on this, attempted to create a custom serializer but the includeData method is never called. |
Be careful of which version you are using. I removed the Sounds like you've both got different versions as one is using |
Same problem here. I'm using fractal 0.8.3 with Dingo/Api and it's not possible to create a custom serializer the way I want it. Therefore it is not possible to remove the "data"-key in included elements. |
Same in version 0.9.*. The In other case it is not possible to change default behavior and remove annoying "data" key for embedded data. |
So somebody should fix this. Between you there has to be somebody who can get a PR over to me. I have zero free time for this for the next few weeks. I'd really appreciate it. |
The solution won't need to change Fractal code. If you wouldn't like to have your response wrapped with 'data' key create a new serializer or extend existing one and override following methods like that: public function collection($resourceKey, array $data)
{
return ($resourceKey && $resourceKey !== 'data') ? array($resourceKey => $data) : $data;
}
public function item($resourceKey, array $data)
{
return ($resourceKey && $resourceKey !== 'data') ? array($resourceKey => $data) : $data;
} It's easy and works perfectly! |
Please note that this works only with fractal version Like @mediaholding said, write your own serializer and override the /**
* Serialize the data.
*
* @param array $data
* @return array
*/
public function serializeData($resourceKey, array $data)
{
// todo update fractal to 0.9.x and remove this workaround (and probably the whole method)
// We have to use a workaround since fractal 0.8.* apparently has no other
// way to remove the data attribute from included elements
$backtrace = debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT, 5);
if($backtrace[2]['function'] === 'processIncludedResources')
{
return $data;
}
return array('data' => $data);
} |
Based on @mediaholding I am using the following solution. Notice that by default, when /**
* Create a new Serializer in your project
*/
use League\Fractal\Serializer\ArraySerializer;
class DataArraySerializer extends ArraySerializer
{
public function collection($resourceKey, array $data)
{
if ($resourceKey === false) {
return $data;
}
return array($resourceKey ?: 'data' => $data);
}
public function item($resourceKey, array $data)
{
if ($resourceKey === false) {
return $data;
}
return array($resourceKey ?: 'data' => $data);
}
} # Set the serializer on fractal manager
$manager = new League\Fractal\Manager();
$manager->setSerializer(new DataArraySerializer());
# Or if you are using the ellipsesynergie/api-response package for Laravel
$this->response->getManager()->setSerializer(new DataArraySerializer()); It is fully backwards compatible, except that if you pass For example, I have this transformer: class FriendshipTransformer extends TransformerAbstract
{
protected $availableIncludes = [
'user',
];
public function transform(Friendship $friendship)
{
return $friendship->toArray();
}
public function includeUser(Friendship $friendship)
{
// pass false as resourceKey
return $this->item($friendship->user, new UserTransformer, false);
}
} Edit: fixed issue that igored the resource key, thanks @ddctd143 for pointing out |
@boukeversteegh Your implementation does not allow to use custom data key, because in your overriding methods $resourceKey isn't used at all. At example, if you need to specify data key, but you need to use a custom key, then this implementation should work
|
oh you are right, that was a pretty bad mistake. let me correct. i would like this behavior:
let me rewrite |
I am working on a PR to implement optional, yet customizable resource keys (wrapper arrays) but I'm having trouble understanding the intention behind DataArraySerializer and ArraySerializer. Hopefully @localheinz or @philsturgeon can help out. From the unit tests, it seems that DataArraySerializer is ignoring the resourceKey on purpose. I.e: even though the transformer sets the resourceKey to "author", the array is returned as Otherwise I could add this feature to ArraySerializer, but that one does not wrap items. In my opinion neither serializers make much sense. The ArraySerializer uses the resourceKey only for collections, and does not allow disabling. The DataSerializer also wraps single items, but does not allow overriding, nor disabling the data key. IMO all of this functionality could and should be supported by a single Serializer such as the one I proposed above. Now the question is should we support this flexibility by breaking compatibility, or by adding a new serializer, and if so what should it be called.
What do you think? I will PR soon if we can come up with a nice solution. |
@boukeversteegh Maybe call it |
@boukeversteegh did you create a PR for that already, and has it been merged? |
New to fractal, and ran into this today. Our data structures nest a lot of includes. My front end dev is not happy with having to write object keys like this:
It gets pretty long winded.
Status of this PR? |
One idea is to write an abstraction layer instead of trying to make the API output data in exactly the right structure for the front end developer?
Generally different front end developers want different things, so you can't please them all.
|
I will +1 this I will also be writing a custom serializer to make my api more readable. Is nesting object attributes in a data property a standard I should be aware of or is this just a quirk of the library? edit: Also thanks for this library, hoping to use it regularly now that I am back on php. |
It’s incredibly common to use an envelope yes, which isn’t ideal but is required to add metadata to a collection as this library does.
…--
Phil Sturgeon
@philsturgeon
On Jan 27, 2018, at 23:49, Michael Nelson ***@***.***> wrote:
I will +1 this I will also be writing a custom serializer to make my api more readable. Is nesting object attributes in a data property a standard I should be aware of or is this just a quirk of the library?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or mute the thread.
|
To wrap the response with protected $listen = [
'Dingo\Api\Event\ResponseWasMorphed' => [
'App\Listeners\FormatDingoResponse'
]
]; class FormatDingoResponse
{
public function handle(\Dingo\Api\Event\ResponseWasMorphed $event)
{
$data = isset($event->content['data']) ? $event->content['data'] : $event->content;
unset($data['meta']);
$meta = isset($event->content['meta']) ? $event->content['meta'] : [];
$event->content = ['data' => $data, 'meta' => $meta];
}
} |
better to overwrite the serializer within dingo class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*
* @return void
*/
public function register()
{
if ($adapter = app('api.transformer')->getAdapter()) {
$manager = $adapter->getFractal();
$manager->setSerializer(new \App\Transformers\Serializer\DataArraySerializer());
}
}
} |
PHP8 changed types support, now it is not working, In new version need add false var type in function. Temporary make like this =(
Usage:
|
Is there a way to not have the
data
key as part of the included elements, while still keeping it for the top level response data?The text was updated successfully, but these errors were encountered: