Comments (6)
To be honest, this format seems a little bit off. What happened with the original where getComments(Post $post): array would actually be getComments(array $posts): array?
from graphqlite.
Maybe I just don't see exactly how does it work, but let me try though:
<?php
/**
* @Type
*/
class PostType {
/**
* @Field(prefetchMethod="eagerLoadComments")
* @return Comment[]
*/
public function getComments(Post $post, $promisedData): array
{
return array_filter($promisedData, function ($comment) use ($post) {
return $post->getId() === $comment['post_id'];
});
}
/**
* @param Post[] $posts
* @return array
*/
public function eagerLoadComments(iterable $posts, bool $hideSpam, int $filterByScore)
{
$ids = []
foreach ($posts as $post) {
$ids = [] = $post->getId();
}
$this->getCommentsByPostIds($ids);
}
private function getCommentsByPostIds(array $ids): array
{
return [
[
'post_id' => 1,
'comment' => 'Hello world',
],
[
'post_id' => 1,
'comment' => 'Hello world2',
],
[
'post_id' => 2,
'comment' => 'Hello world3',
],
];
}
}
Is this what you wanted to achieve?
from graphqlite.
Hey @golaod ,
Your example is perfect, you got it right.
Indeed, the idea we first talked about was different. My first idea was something like:
/**
* @Type
*/
class PostType {
/**
* @BatchField()
* @param Post[] $posts
* @return Comment[][]
*/
public function getComments(array $posts): array
{
// ...
}
}
I've been talking with @homersimpsons for quite some time about it. He convinced me this is a somewhat better alternative.
Here are the main points:
Regarding method signature
/**
* @Field(prefetchMethod="eagerLoadComments")
* @return Comment[]
*/
public function getComments(Post $post, $promisedData): array
This method signature is quite similar to the usual way we create fields. It is easier to understand (it is obvious that the field "comments" is of type "Comment[]".
Compare this to:
/**
* @BatchField()
* @param Post[] $posts
* @return Comment[][]
*/
public function getComments(array $posts): array
{
// ...
}
The return type ("Comment[][]") will map to Comment[] in GraphQL. It is obvious to both of us, but it could cause problems to beginners.
Regarding implementation
With this signature:
public function getComments(array $posts): array
the keys of the returned array must match the keys of the $posts array (otherwise, GraphQLite cannot know by itself what comments are linked to what posts).
Doing the matching on the keys of the arrays is error-prone. Also, what is GraphQLite supposed to return if some keys are missing or if there are some additional keys passed by the developer? Should it trigger an error?
Compare this to the solution proposed by @homersimpsons:
/**
* @Field(prefetchMethod="eagerLoadComments")
* @return Comment[]
*/
public function getComments(Post $post, $promisedData): array
Here, there is absolutely no possible doubt. The returned comments are matching the "$post" passed in argument. The method signature is way more strict than in the other solution and less things can go awkward.
Does it make sense? Or do you think another way of doing things we did not think about?
from graphqlite.
How does it know about $promisedData
? Asking because the field can still have inputs, so is there any position it should be at or what?
from graphqlite.
/**
* @Field(prefetchMethod="eagerLoadComments")
* @return Comment[]
*/
public function getComments(Post $post, $promisedData): array
GraphQLite will detect the prefetchMethod
attribute in the @field annotation. If the prefetchMethod
attribute is present, the 2nd argument of the method MUST be the promisedData (returned by the prefetch method).
Input arguments come either in third position and afterwards, or in the prefetch method:
/**
* @Type
*/
class PostType {
/**
* @Field(prefetchMethod="prefetchComments")
* @param Post $post
* @param mixed $prefetchedComments
* @return Comment[]
*/
public function getComments(Post $post, $prefetchedComments, int $maxCommentLength): array
{
// In this sample, the input arguments of the comments field are:
// - maxCommentLength: Int
// - hideSpam: Bool
// - filterByScore: Int
}
/**
* @param Post[] $posts
* @return mixed
*/
public function prefetchComments(iterable $posts, bool $hideSpam, int $filterByScore)
{
// Parameters passed after the first parameter (hideSpam, filterByScore...) are automatically exposed as GraphQL arguments for the "comments" field.
}
}
from graphqlite.
👍
from graphqlite.
Related Issues (20)
- Support readonly input classes with constructors HOT 20
- Implement Persisted Queries mechanism to easily allow server-side Caching HOT 14
- Field nullable union type is throwing an error HOT 1
- Performance problem even for small query on big schema. HOT 33
- Improve #[InjectUser] to throw authentication errors HOT 1
- First party support for `void` return type HOT 3
- Please, publish a new version HOT 1
- Extension packages are unmaintained or don't support latest features HOT 11
- doctrine/annotations should be upgraded to v2 HOT 2
- Mutability concerns HOT 5
- Cleanup and deprecate confusing annotations HOT 2
- New patch version HOT 3
- Mapping multiple php object representations for a single resource to one graphql ObjectType HOT 4
- Automatic query complexity HOT 1
- Empty request body parsing error for automatic persisted queries HOT 14
- prefetchMethod does not work HOT 12
- Arguments description in schema HOT 3
- Undocumented Error or posible dead code HOT 3
- ExtendType and Type with class argument don't work
- Defining fields in type by trait from different namespace ends with error for relative type declarations HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from graphqlite.