Comments (4)
Hey @hailwood, great question!
graphql-php
(which is what this package is built on) has a listOf
type that can be used when you just want to return a list of types. A connection
is better suited for when you want to do some pagination.
So if you wanted to have a list of users at the top level of your query you would just need to create a query which has a return type of a list of users like so:
Notice that the return type is wrapped in Type::listOf
use GraphQL;
use App\Models\User;
use GraphQL\Type\Definition\Type;
use Nuwave\Lighthouse\Support\Definition\GraphQLQuery;
class UsersQuery extends GraphQLQuery
{
/**
* Type query returns.
*
* @return Type
*/
public function type()
{
return Type::listOf(GraphQL::type('user'));
}
/**
* Available query arguments.
*
* @return array
*/
public function args()
{
// ...
}
/**
* Resolve the query.
*
* @param mixed $root
* @param array $args
* @return mixed
*/
public function resolve($root, array $args)
{
return User::all();
}
}
If you had users and wanted to return a list of tasks as a field with arguments you could do this:
use GraphQL;
use GraphQL\Type\Definition\Type;
use GraphQL\Type\Definition\EnumType;
use Nuwave\Lighthouse\Support\Definition\GraphQLType;
use Nuwave\Lighthouse\Support\Interfaces\RelayType;
use App\Models\User;
class UserType extends GraphQLType implements RelayType
{
// ...
/**
* Available fields of Type.
*
* @return array
*/
public function fields()
{
return [
// ...
'tasks' => [
'args' => [
'status' => [
'type' => new EnumType([
'name' => 'UserStatus',
'values' => [
'OPEN' => ['value' => 1],
'CLOSED' => ['value' => 0]
],
])
],
],
'type' => Type::listOf(GraphQL::type('task')),
'resolve' => function (User $user, array $args) {
$tasks = $user->tasks();
if ($status = array_get($args, 'status')) {
$tasks->where('status', $status);
}
return $tasks->get();
}
],
];
}
}
Hope that helps, but let me know if you still have questions!
from lighthouse.
Aha! Thanks @chrissm79,
I was missing,
return Type::listOf(...);
I was trying
return GraphQL::listOf(GraphQL::type('user'));
which obviously doesn't work 👍 .
One last part of is how would we paginate these (I'm mostly interested in a relay style approach, but both relay and non-relay would probably be useful for others).
Also, is there any way we can contribute to the documentation?
I wouldn't mind writing up some docs on these things.
I had contemplated starting some pages on the wiki, but I don't want to split the docs over two areas.
Cheers,
Matt
from lighthouse.
Alrighty, so after running through learnrelay.org I've managed to answer my own question. tl;dr You don't. That's not how relay works :)
from lighthouse.
Hey @hailwood,
Sorry for the delayed response! You are correct that you don't necessarily paginate a list alone, but you can create a new Type
to get it work and w/ Lighthouse you have two options.
Regular Pagination
First, you can create your own Type
that has the fields required for pagination (such as page, total, etc) plus the listOf
containing a list of the GraphQL type you want to provide. For example:
class UserTasks extends GraphQLType
{
/**
* Attributes of Type.
*
* @var array
*/
protected $attributes = [
'name' => 'UserTasks',
];
// ...
/**
* Available fields of Type.
*
* @return array
*/
public function fields()
{
return [
'page' => [
'type' => Type::int(),
],
'count' => [
'type' => Type::int(),
'description' => 'How many tasks to paginate',
],
'total' => [
'type' => Type::int(),
'description' => 'Total number of user tasks.',
],
'tasks' => [
'type' => Type::listOf(GraphQL::type('task'))
],
];
}
}
Then (in this example) you would just register it and attach it to your UserType
and add some arguments like so:
// fields on UserType
[
// ..
'tasks' => [
'type' => GraphQL::type('userTasks'),
'args' => [
'page' => [ 'type' => Type::int() ],
'count' => [ 'type' => Type::int() ],
],
'resolve' => function (User $user, array $args) {
$count = array_get($args, 'count', 15);
$page = array_get($args, 'page', 1);
$tasks = $user->tasks()->paginate($count, ['*'], 'page', $page);
return [
'page' => $tasks->currentPage(),
'count' => $tasks->count(),
'total' => $tasks->total(),
'tasks' => $tasks->items(),
];
}
],
]
Relay Pagination
Alternatively, you can use Lighthouse's built in connection helper which matches the Relay spec. First, you need to add the RelayConnection
Trait to the model you want to paginate over (in this case it would be the Task
model;
use Illuminate\Database\Eloquent\Model;
use Nuwave\Lighthouse\Support\Traits\RelayConnection;
class Task extends Model
{
use RelayConnection;
// ...
}
Then create a new connection
$ php artisan lighthouse:connection UserTasks
Customize the generated connection
namespace App\Http\GraphQL\Connections;
use GraphQL\Type\Definition\ResolveInfo;
use Nuwave\Lighthouse\Support\Interfaces\Connection;
class UserTasks implements Connection
{
/**
* Get the name of the connection.
* Note: Connection names must be unique
*
* @return string
*/
public function name()
{
return 'UserTasks';
}
/**
* Get name of connection.
*
* @return string
*/
public function type()
{
return 'task';
}
/**
* Available connection arguments.
*
* @return array
*/
public function args()
{
return [];
}
/**
* Resolve connection.
*
* @param mixed $parent
* @param array $args
* @param mixed $context
* @param ResolveInfo $info
* @return mixed
*/
public function resolve($user, array $args, $context, ResolveInfo $info)
{
// we have access to `getConnection` here because of the trait we added
return $user->tasks()->getConnection($args);
}
}
and finally, just add the connection as a field to the UserType
[
// ...
'tasks' => GraphQL::connection(new App\Http\GraphQL\Connections\UserTasks())->field(),
]
That's it! It will create a new Connection Type that has all of the required Relay fields for a connection!
Hopefully that helped, but let me know if you still have questions!
from lighthouse.
Related Issues (20)
- Segmentation fault when handling large payloads HOT 8
- Requesting local scopes can pass parameters HOT 1
- New directive that mirrors functionality of `whereHas` for relations (not `@whereHasConditions`) HOT 1
- `make setup` failed on macOS
- Access context in `FieldMiddleware` HOT 3
- CanArgs is defined twice in schema-directives.graphql
- `extend scalar X` directives are lost
- @canFind is missing "model" argument in graphql definition HOT 1
- Allow to customize the unique key for `PaginatedModelsLoader`
- artisan lighthouse:union stub appears to be incorrect HOT 1
- Problem with subscription middleware HOT 2
- An error occurs in the SubscriptionRegistry when sending a subscription event via Subscription::broadcast with Laravel Octane (Swoole) HOT 5
- Laravel v11 support dependancy missing
- Enum Support for Morph Types HOT 1
- Mutation transaction seem not work HOT 4
- Failed to find class App\GraphQl\Queries\TodoQuery in namespaces [] for directive @paginate
- @whereNull and @whereNotNull No directive found!
- GraphQL subscription with Laravel Reverb HOT 3
- input.id in @can(find: ) HOT 1
- Throttle directive sets wrong decay time HOT 4
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 lighthouse.