Giter VIP home page Giter VIP logo

Comments (6)

golaod avatar golaod commented on July 28, 2024

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.

golaod avatar golaod commented on July 28, 2024

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.

moufmouf avatar moufmouf commented on July 28, 2024

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.

golaod avatar golaod commented on July 28, 2024

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.

moufmouf avatar moufmouf commented on July 28, 2024
/**
 * @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.

golaod avatar golaod commented on July 28, 2024

👍

from graphqlite.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.