Avoid calling model accessor twice through default resolver
Open
Nobody has claimed this yet.
enhancement
- Dominant language
- PHP
- Stars
- 3.5k
- Forks
- 468
- Avg merge
- 3h 9m
- Merged PRs (30d)
- 2
Description
Describe the bug
When I call a model accessor from GraphQL query Lighthouse calls it twice. When I call it from outside of Lighthouse it is being called only once.
Expected behavior/Solution
When I call the accessor it should only be called once.
Steps to reproduce
- Create a simple model and add accessor into the model, I have added dump() to understand how many time this accessor is being called.
namespace App;
use Illuminate\Database\Eloquent\Model;
class Brand extends Model
{
public function getTestAttribute() {
dump('TEST');
return 'test';
}
}
- Define Brand type in GraphQL
type Brand {
id: ID!
franchise_id: Int
country_id: Int
name: String!
website: String
created_at: DateTime
updated_at: DateTime
test: String
}
- Add GraphQL query to the schema
brand(id: ID @eq): Brand @guard(with: ["api"]) @find(model: "App\\Brand")
- Call it the query by adding test attribute
query($id:ID) {
brand (id: $id) {
id
test
}
}
- Examine the result, in the query response I see result of the dump('TEST') two times and json response itself.
"TEST"
"TEST"
{"data":{"brand":{"id":"5","test":"test"}}}
- Change the model accessor to return null rather than a string
namespace App;
use Illuminate\Database\Eloquent\Model;
class Brand extends Model
{
public function getTestAttribute() {
dump('TEST');
return null;
}
}
- Examine this time result of the dump('TEST') only one and json response itself
"TEST"
{"data":{"brand":{"id":"5","test":null}}}
- This time I will try to access the accessor outside of Lighthouse, to do that first restore model accessor to return string again
namespace App;
use Illuminate\Database\Eloquent\Model;
class Brand extends Model
{
public function getTestAttribute() {
dump('TEST');
return 'test';
}
}
- Try to access model's accessor trough Laravel's web.php, to do that add the following code at the top of the web.php
Route::get('/', function () {
return \App\Brand::first()->test;
});
- Try it out by going to localhost from the browser, I can see from the response that this time dump('TEST') only called once
"TEST"
test
Lighthouse Version
v4.18.0
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
The report provides no repository file or test entry point. Start by reproducing the issue with the Brand accessor and GraphQL query shown, then trace the default resolver's handling of the test field; done means the accessor is called once while the response remains correct.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- laravel, php
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100