chkimes / graphql-net

Convert GraphQL to IQueryable
MIT License
891 stars 86 forks source link

How create the query with pagination option #76

Closed janskoruba closed 7 years ago

janskoruba commented 7 years ago

I want to create list of users with option for pagination.

For example - Get first 30 users.

How can I do this?

Thank you.

chkimes commented 7 years ago

You can simply use LINQ's .Take and .Skip methods in your query definition. Paging parameters can be passed in via the args object. For example:

schema.AddListField("usersPaged",
    new { page = 0 },
    (db, args) => db.Users.Skip(args.page * 30).Take(30));
janskoruba commented 7 years ago

If I want to generate the SQL query dynamicly according GraphQL query is it possible?

I've wondered about scenario where I have a query like this:

{
user: {
 id,
 name,
 friends: [
 id,
 name
 ]
}
}
SELECT id, name ... FROM dbo.[User]
INNER JOIN dbo.[UserFriends ] ....

and simple version only list of users with id a name (without friends):

{
user: {
 id,
 name
}
}

SELECT id, name FROM dbo.[User]

Is it possible create map GraphQL to specific SQL command like above with pagination?

chkimes commented 7 years ago

Yes, that is possible and is essentially the goal of this library. However, we don't convert directly to SQL. This library converts GraphQL to IQueryable which is what ORMs in .NET use as an abstraction for a query. If you're already using an ORM (like Entity Framework or NHibernate) then they will handle converting IQueryable to SQL.

janskoruba commented 7 years ago

OK, I see, please, can you give me a sample code, how can I do that above? :)

I think is it possible create GraphQL query which will be to translate the IQueryable with Take and Skip or is necessary create this operation manually?

And how can I define a list of available queries? I want to disallow send any queries to database from UI.

Thank you for clarification.

chkimes commented 7 years ago

I would suggest reading through a few pages of the documentation (https://ckimes89.gitbooks.io/graphql-net/content/) and maybe also checking out some of the example projects (https://github.com/ckimes89/graphql-net/tree/master/examples/01-simple-query). Those go through setting up a schema with GraphQL.Net and Entity Framework and using it to pull data from a database. That should give you a good primer on working with this library.

If you want to restrict which GraphQL queries can be run, you will need to do that before passing the query to GraphQL.Net. There is no built-in support for this.

janskoruba commented 7 years ago

Thank you Chad for your suggestion. I'll read it.

janskoruba commented 7 years ago

Is it possible use this library with .NET Core? :)

chkimes commented 7 years ago

Not currently - there is an open issue #34 that is tracking it. The delay has been waiting on F# support for .NET Core/Standard, which just released with VS2017, and also waiting on dependency libraries to update and support .NET Core (FParsec and FParsec-Pipes).

janskoruba commented 7 years ago

OK, thank you. :)

wc-matteo commented 7 years ago

@ckimes89 I'd like to change the IQueryable depending on the graphql input query like https://github.com/ckimes89/graphql-net/issues/76#issuecomment-287357153.

You've said that is possible and is essentially the goal of this library but I don't see how, seeing that the graphql input query is not accessible when you add fields.

Sorry if you've already answered it with:

If you want to restrict which GraphQL queries can be run, you will need to do that before passing the query to GraphQL.Net

(but I'm not sure what you mean there)

chkimes commented 7 years ago

@wc-matteo Check out the last few paragraphs of this page in the docs: https://ckimes89.gitbooks.io/graphql-net/content/docs/basics/build_a_schema.html

but I don't see how, seeing that the graphql input query is not accessible when you add fields.

The parameters passed to each field in the query are available to be used. Notice how in this setup line:

schema.AddField("user", new { id = 0 }, (db, args) => db.Users.Where(u => u.Id == args.id).FirstOrDefault());

We have new { id = 0 } and later we use args.id. The first part is defining what arguments can be passed to the field, and the second is using the passed in argument when executing the query. If you want to handle pagination (as in this original issue), then use the parameters as arguments to the .Skip() and .Take() LINQ methods.

wc-matteo commented 7 years ago

Thanks for the answer @ckimes89.

I meant changing the db query based on the fields in the input query (e.g. in the comment I linked, you could save a join if the input query doesn't specify the friends property)

chkimes commented 7 years ago

@wc-matteo Ah, I see. Yes, this works by default. We only join to other tables if it's necessary to produce results for the query.

wc-matteo commented 7 years ago

Nice! Thank you @ckimes89.