- Notifications
You must be signed in to change notification settings - Fork 18
Description
| Version |
|---|
| 1.0.3 |
TL;DR: In scenarios where there are many relationships but a client only wants to refresh a single relationship, the serializer seems to require eager-loading all relationships before filtering down to a specific relationship to include.
In the theoretical example below:
class Blog implements ResourceInterface, LinksInterface { use ResourceTrait; public function extraFields() { return [ 'author', 'comments', 'likes', ]; } public function getAuthor() { return $this->hasOne(Author::className(), ['id' => 'author_id']); } public function getComments() { return $this->hasMany(Comment::className(), ['id' => 'blog_id']); } public function getLikes() { // complicated SQL packaged up into a model runs here ... } }If an API client wants to do a /api/blogs/3?include=comments without triggering the complicated SQL in the likes relationship, the getLikes() will still have been loaded using the default ResourceTrait and default Serializer due to the resolveFields() foreach here ...
yii2-json-api/src/ResourceTrait.php
Lines 56 to 68 in f2bee3d
| public function getResourceRelationships() | |
| { | |
| $relationships = []; | |
| $fields = []; | |
| if ($this instanceof Arrayable) { | |
| $fields = $this->extraFields(); | |
| } | |
| foreach ($this->resolveFields($fields) as $name => $definition) { | |
| $relationships[$name] = is_string($definition) ? $this->$definition : call_user_func($definition, $this, $name); | |
| } | |
| return $relationships; | |
| } |
Specifically, line 65 there eager-loads all relationships in the extraFields method even if those relationships are not included in any way ...
Do you think we can work out how to not pre-populate those relationships until we're sure we want them in the payload? Combining that desire with the option to add links could get a bit tricky ...
Interested in your thoughts!