Skip to content
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

always including data for every relationship #127

Closed
robinstraub opened this issue Sep 15, 2021 · 4 comments
Closed

always including data for every relationship #127

robinstraub opened this issue Sep 15, 2021 · 4 comments
Milestone

Comments

@robinstraub
Copy link

Hi,

I am building an API and am used to produce resources that always have the data segment of their relationships. I used to use this on my frontend using this former package version. I came across this section of the official documentation explaining how to provide it using the resource classes.

Is there a way to always provide the data, without having to write resource classes for every schema and specifying the alwaysIncludeData() on every relationship ?

@DenisaHalmaghi
Copy link

Hi @robinstraub . I don't think you can skip the creation of the resource/schema classes, but maybe this section in the documentation can help with the include paths.

@robinstraub
Copy link
Author

Thanks for your reply, I ended up creating a trait for overloading the relationships() method of the JsonApiResource classes, which let me update the default content of the relationships:

<?php

namespace App\JsonApi;

use Illuminate\Http\Request;
use LaravelJsonApi\Contracts\Resources\Serializer\Relation as SerializableRelation;

trait NormalizeRelationships
{
    /**
     * Get the resource's relationships.
     *
     * @param Request|null $request
     * @return iterable
     */
    public function relationships($request): iterable
    {
        foreach ($this->schema->relationships() as $relation) {
            if ($relation instanceof SerializableRelation && $relation->isNotHidden($request)) {
                yield $relation->serializedFieldName() => $this->relation($relation->serializedFieldName())->alwaysShowData()->withoutLinks();
            }
        }
    }
}

which let me have fairly simple JsonApiResource classes, given I don't need to customize the resource content :

<?php

namespace App\JsonApi\V1\Orders;

use App\JsonApi\NormalizeRelationships;
use LaravelJsonApi\Core\Resources\JsonApiResource;

class OrderResource extends JsonApiResource
{
    use NormalizeRelationships;
}

Aside from the hassle of creating the resource classes manually, this works fine for my use case.

@lindyhopchris lindyhopchris added this to the 1.x milestone Jan 2, 2022
@lindyhopchris
Copy link
Contributor

To better support this use case, 1.1 (not yet tagged) adds the following:

The JsonApiResource class now has a protected serializeRelation method that you can overload to change the default serialization. I.e. you wouldn't now have to overload the relationships() method, and instead could do:

protected function serializeRelation(SerializableRelation $relation): JsonApiRelation
{
    return parent::serializeRelation($relation)->alwaysShowData()->withoutLinks();
}

Also, if you wanted to make this change across the whole of your API (i.e. for every resource), you can now change the default class that is used for for the JSON:API resource. In your service provider:

use LaravelJsonApi\Laravel\LaravelJsonApi;

public function register(): void
{
    LaravelJsonApi::defaultResource(MyResourceClass::class);
}

@lindyhopchris
Copy link
Contributor

Closing as will be in the 1.1 release.

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

No branches or pull requests

3 participants