Laravel Rebing GraphQL – Pagination on sub relation

Laravel Rebing GraphQL – Pagination on sub relation


0

I’m trying to paginate the relations through a parent pivot.

A user has topics and a topic can have multiple users. Multiple users can be the owner of a topic. A topic has messages.

class Topic extends Model
{
    //Casts Fillables etc. 

    public function user(): BelongsToMany
    {
        return $this->belongsToMany(User::class, 'topic_users', 'topic_uuid', 'user_uuid')
            ->withPivot([
                'uuid',
                'user_uuid',
                'is_owner',
                'created_at',
                'updated_at',
            ])
            ->using(User::class);
    }

    public function messages(): HasMany
    {
        return $this->hasMany(Message::class, 'topic_uuid', 'uuid');
    }
}
class User extends Authenticatable
{
    //Casts Fillables etc

        public function topics(): BelongsToMany
    {
        return $this->belongsToMany(Topic::class, 'topic_users')
            ->withPivot(
                'uuid',
                'is_owner',
                'created_at',
                'updated_at'
            );
    }
}

TopicType


namespace AppGraphQLTypes;

use AppModelsTopic;
use GraphQLTypeDefinitionType;
use RebingGraphQLSupportFacadesGraphQL;
use RebingGraphQLSupportType as GraphQLType;

class TopicType extends GraphQLType
{
    protected $attributes = [
        'name'        => 'Topic',
        'description' => 'The topic and it's messages',
        'model'       => Topic::class,
    ];

    public function resolveMessagesField($root, $args) {
        return $root->messages()->paginate($args['limit'], ['*'], 'page', $args['page']);
    }

    public function fields(): array
    {
        return [
            'uuid' => [
                'type'        => Type::string(),
                'description' => 'The UUID of the Topic',
            ],
            'title' => [
                'type'        => Type::string(),
                'description' => 'The title of the Topic',
            ],
            'slug' => [
                'type'        => Type::string(),
                'description' => 'The slug of the Topic',
            ],
            'key' => [
                'type'        => Type::string(),
                'description' => 'The unique key that identifies the topic',
            ],

            'last_message_at' => [
                'type'        => Type::string(),
                'description' => 'UTC Timestamp of when the last message has been send',
            ],
            'last_message' => [
                'type'        => Type::nonNull(GraphQL::type('Message')),
                'description' => 'The last message that has been sent in this topic',
            ],
            'messages' => [
                'type' => GraphQL::paginate('Message'),
                'description' => 'The messages in this topic',
                'args' => [
                    'limit' => [
                        'name' => 'limit',
                        'type' => Type::int(),
                        'rules' => ['required', 'numeric', 'min:1', 'max:20'],
                    ],
                    'page' => [
                        'name' => 'page',
                        'type' => Type::int(),
                    ],
                ]
            ]
        ];
    }
}

Message Type

namespace AppGraphQLTypes;

use AppModelsMessage;
use GraphQLTypeDefinitionType;
use RebingGraphQLSupportFacadesGraphQL;
use RebingGraphQLSupportType as GraphQLType;

class MessageType extends GraphQLType
{
    protected $attributes = [
        'name'        => 'Message',
        'description' => 'Represents the message type',
        'model'       => Message::class
    ];

    public function fields(): array
    {
        return [
            'uuid' => [
                'type'        => Type::nonNull(Type::string()),
                'description' => 'The UUID of the message',
            ],
            'topic_uuid' => [
                'type'        => Type::nonNull(Type::string()),
                'description' => 'The UUID of the Topic',
            ],
            'title' => [
                'type'        => Type::string(),
                'description' => 'Message Title',
            ],
            'message' => [
                'type'        => Type::string(),
                'description' => 'The actual message',
            ],
            'received_at' => [
                'type'        => Type::nonNull(Type::string()),
                'description' => 'The timestamp the server has received the message',
            ],
            'processed_at' => [
                'type'        => Type::string(),
                'description' => 'The timestamp the server was done processing the message',
            ],
        ];
    }
}

TopicQuery

<?php

declare(strict_types=1);

namespace AppGraphQLQueries;

use AppGraphQLHelpersGraphQLHelpers;
use AppModelsTopic;
use Closure;
use GraphQLTypeDefinitionResolveInfo;
use GraphQLTypeDefinitionType;
use IlluminateSupportFacadesAuth;
use RebingGraphQLSupportFacadesGraphQL;
use RebingGraphQLSupportQuery;

class TopicQuery extends Query
{
    protected $attributes = [
        'name'        => 'topic',
        'description' => 'A query to fetch the topic and the last 25 messages',
    ];

    public function type(): Type
    {
        return GraphQL::type( 'Topic');
    }

    public function args(): array
    {
        return [
            'uuid' => [
                'type'        => Type::nonNull(Type::string()),
                'description' => 'The UUID of the Topic',
            ],
            'limit' => [
                'type'         => Type::int(),
                'defaultValue' => GraphQLHelpers::DEFAULT_PAGE_SIZE,
                'description'  => 'The amount of items you want to fetch',
                'rules'        => ['max:50'],
            ],
            'page' => [
                'type'         => Type::int(),
                'defaultValue' => GraphQLHelpers::DEFAULT_PAGE_NUMBER,
            ],
        ];
    }

    public function resolve($root, array $args, $context, ResolveInfo $resolveInfo, Closure $getSelectFields)
    {
        $fields = $getSelectFields();

        return= Topic::query()->whereHas('user', function ($query) {
            return $query->where('user_uuid', '=', Auth::guard('graphql')->user()->uuid);
        })
            ->where('uuid', $args['uuid'])
            ->select($fields->getSelect())
            ->with('messages')
            ->paginate($args['limit'], ['*'], 'page', $args['page']);
    }
}

The query I’m trying to achieve:

{
  topic(uuid: "7ca8af62-8bb5-4013-9141-82483fea06fa") {
    uuid
    title
    messages(limit: 2, page: 1) {
      data {
        uuid
      }
    }
  }
}

The args are passed correctly

Laravel Rebing GraphQL - Pagination on sub relation

I still get the 10 first messages, while the topic itself is correctly fetched.


Load 6 more related questions


Show fewer related questions

0



Leave a Reply

Your email address will not be published. Required fields are marked *