Nested Queries in GraphQL
Introduction And Context Setting
Welcome to the lesson on handling more complex data queries as part of the "Comprehensive Intro to GraphQL in Ruby" course. In the previous lesson, you learned how to set up a GraphQL server and define mutations to modify data. In this lesson, we'll shift focus to reading data in more sophisticated ways. Specifically, we'll set up nested queries in GraphQL to handle intricate relationships between data types, such as authors and books.
Defining The Schema With Nested Queries
To handle nested queries, we need a schema that represents our data types and their relationships.
-
Define Data Types.
We'll create
AuthorandBooktypes with fields that reference each other:RubyAuthorTypehas fieldsid,name, andbooks. The[BookType]syntax means this field returns an array ofBookTypeobjects. Note thatnull: truehere means the entire list can be null (i.e., the field itself may returnnil), not that individual books within the list can be null. If you wanted to allow null elements inside a non-null array, you would write[BookType, null: true], null: falseinstead.BookTypehas fieldsid,title, and anauthor, which is of typeAuthorType. Here,null: truemeans the author field itself can be null (e.g., if a book has no associated author).
-
Sample Data.
Define some sample data to work with:
RubyThis data will be used to simulate a small library. Notice that each book stores its author as an
idstring (e.g.,'1'), not as a full author hash. The resolvers we define next will be responsible for looking up the actual author data from this ID.
Implementing Resolvers For Nested Queries
Resolvers are responsible for fetching the data defined in your schema.
-
Define Resolvers.
Here's how you can write resolvers to handle nested queries:
Ruby- The
QueryTyperesolvers return the sample data forbooksandauthors. - The
BookTyperesolver finds the author of a given book. - The
AuthorTyperesolver filters books written by a given author.
You'll notice that the resolver methods use
object— for example,object[:author]andobject[:id]. Ingraphql-ruby,objectis a built-in method available inside every type class. It refers to the underlying Ruby data (in our case, a hash) that the current GraphQL type is wrapping. So when GraphQL is resolving a specificBookType,objectis the book hash (e.g.,{ id: '1', title: 'The Hobbit', author: '1' }), andobject[:author]retrieves the author's ID from that hash. Similarly, insideAuthorType,objectis the author hash, andobject[:id]gives you that author's ID. - The
-
Initialize The Schema And Server.
Combine the types to set up the schema and server:
RubyWhen you run your
graphql_ruby/main.rbfile, it should print:text
Testing The Nested Queries
Now that your server is up and running, let's test the nested queries using a real-world example.
-
Define The Query.
In a file called
run.rb, write a query to fetch books and their authors:Ruby -
Run The Query.
Running this function should give you the following output:
JSONThis confirms the server correctly handles your nested queries and returns the expected data.
Summary And Next Steps
In this lesson, you've learned how to handle more complex data queries in GraphQL by setting up nested queries with graphql-ruby and Sinatra. You've defined a schema with nested types, implemented resolvers, and tested your queries.
Now, it's time to practice what you've learned. Head over to the practice exercises to solidify your understanding. Try experimenting with more complex queries and relationships to gain a deeper grasp of handling data in GraphQL.
Congratulations on making it this far! Keep practicing to reinforce your newfound skills.
