nuwave / lighthouse

A framework for serving GraphQL from Laravel
https://lighthouse-php.com
MIT License
3.36k stars 438 forks source link

Allow to customize the unique key for `PaginatedModelsLoader` #2516

Closed MissaelAnda closed 5 months ago

MissaelAnda commented 7 months ago

What problem does this feature proposal attempt to solve?

When batchloading relations in the PaginatedModelsLoader using the toJson() method does not warranties the uniqueness of the model, in my case I hide the foreign keys from serialization in a pivot model therefore the content other columns of the pivot are very likely to be reapeted given the unique keys won't be present in the toJson() result.

Which possible solutions should be considered?

My proposal is to allow users to customize the way models uniqueness is checked:

One solution could be to add the BatchloadRegistry or the TBatchLoad resolution to the IoC so it can be binded to a custom one in a ServiceProvider:

class MyServiceProvider extends ServiceProvider
{
    public function register(): void
    {
        $this->app->bind(BatchloadRegistry::class, MyCustomBatchloadRegitry::class);
        // or
        $this->app->bind(PaginatedModelsLoader::class, MyCustomPaginatedModelsLoader::class);
    }
}

Or a more simple and faster solution could be to add an interface or a method that tells the PaginatedModelsLoader the Model has a custom unique key:

In PaginatedModelsLoader line 54:

return $relatedModels->unique(
    // Compare all attributes because there might not be a unique primary key
    // or there could be differing pivot attributes.
    static fn (Model $relatedModel): mixed => method_exists($relatedModel, 'getBatchLoadUniqueKey') ?
        $relatedModel->getBatchLoadUniqueKey() : $relatedModel->toJson(),
    }
);