> The biggest question I have is what's going to process the GraphQL query on the server
It's really not much different from processing a REST-based API request. In theory, you could parse the request and then just execute the necessary SQL to fill out the result.
However, what Facebook's GraphQL library lets you do is define a schema that specifies how each piece of the result is fetched. It's like a declarative API builder. ("GraphQL" is a huge misnomer; it's neither graph-query-oriented, nor is it a query language — it's a protocol.) GraphQL-the-language doesn't make much sense until you look GraphQL-the-library and understand its design.
For example, let's say the GraphQL query is:
query {
story(id: "1") {
text
}
}
Your schema might be declared like this:
const storyType = new GraphQLObjectType({
name: 'Story',
description: 'A story.',
fields() {
id: {
type: new GraphQLNonNull(GraphQLString),
description: 'The ID.',
},
text: {
type: GraphQLString,
description: 'The text.',
}
}
});
const queryType = new GraphQLObjectType({
name: 'Query',
fields() {
story: {
type: storyType,
args: {
id: {
description: 'ID of the story to fetch',
type: new GraphQLNonNull(GraphQLString)
}
},
resolve(root, {id}) {
return SQLDatabase.findStoryById(id)
}
}
}
});
You declare static fields as well as resolver functions that take arguments and are expected to furnish the query with the actual results. You then "execute" the query, which will cause the resolver's to run as they are triggered by parts of the query. For example, if the storyType contains resolvers, any nested queries will invoke them.
I recommend looking at the tests [2] in the GraphQL JS library, because they show some useful examples. There's already a Ruby [1] library for declaring schemas in the same way.
If you're doing SQL underneath, optimizing a GraphQL query into the fewest possible SQL queries might be tricky. For example, let's say each story has an author; doing an author query per story isn't going to cut it; you're going to want to join the authors table. But the outer queryType doesn't know if the query will be asking for the authors. I don't know if the library provides any way to solve this yet.
It's really not much different from processing a REST-based API request. In theory, you could parse the request and then just execute the necessary SQL to fill out the result.
However, what Facebook's GraphQL library lets you do is define a schema that specifies how each piece of the result is fetched. It's like a declarative API builder. ("GraphQL" is a huge misnomer; it's neither graph-query-oriented, nor is it a query language — it's a protocol.) GraphQL-the-language doesn't make much sense until you look GraphQL-the-library and understand its design.
For example, let's say the GraphQL query is:
Your schema might be declared like this: You declare static fields as well as resolver functions that take arguments and are expected to furnish the query with the actual results. You then "execute" the query, which will cause the resolver's to run as they are triggered by parts of the query. For example, if the storyType contains resolvers, any nested queries will invoke them.I recommend looking at the tests [2] in the GraphQL JS library, because they show some useful examples. There's already a Ruby [1] library for declaring schemas in the same way.
If you're doing SQL underneath, optimizing a GraphQL query into the fewest possible SQL queries might be tricky. For example, let's say each story has an author; doing an author query per story isn't going to cut it; you're going to want to join the authors table. But the outer queryType doesn't know if the query will be asking for the authors. I don't know if the library provides any way to solve this yet.
[1] https://github.com/rmosolgo/graphql-ruby
[2] https://github.com/graphql/graphql-js/tree/master/src/__test...