Querying with Arguments
Introduction to Querying with Arguments in GraphQL
In our previous lessons, we've discussed setting up a basic GraphQL server using graphql-ruby and Sinatra, and creating basic types and queries. In this lesson, we will focus on querying with arguments in GraphQL, which allows you to retrieve specific data based on parameters you provide.
To understand querying with arguments, consider that you might want to fetch details about a specific book from a large collection. Instead of retrieving all books and filtering on the client side, you can pass an argument to your query to get just the book you need directly from the server.
Defining the GraphQL Schema with Arguments
To query specific data, we need to extend our GraphQL schema to include arguments. Recall from previous lessons that the schema defines the types of data and the shape of our queries.
In graphql-ruby, we define types as Ruby classes that inherit from GraphQL::Schema::Object. Here's how we define our Book type:
In this type definition:
- The
BookTypeclass inherits fromGraphQL::Schema::Object. - Each field is defined using the
fieldmethod with its name, type, and nullability. - The
idfield uses theIDtype, which is a special GraphQL scalar type for unique identifiers. While technically a string, usingIDsignals that this field represents a unique identifier rather than regular text data, which helps GraphQL tools provide better validation and optimization. - The
null: falseoption signifies that these fields are non-nullable, meaning they must always have a value and cannot benull.
Next, we define our QueryType with arguments:
In this query type:
- The
booksfield returns an array ofBookTypeitems. - The
bookfield takes anidargument of typeID(marked asrequired: true) and returns a singleBookType. - Notice that the
bookfield hasnull: true, which allows it to returnnullif no book with the given ID is found. This is important because thefindmethod in our resolver can returnnilwhen no matching book exists. - The
argumentmethod is used within the field definition to specify the argument.
Creating Resolvers for Queries with Arguments
In graphql-ruby, resolvers are methods defined within the type classes rather than separate resolver objects. These methods handle the logic for fetching and returning data.
First, let's define our sample data:
The resolver methods are already defined in our QueryType class:
Explanation:
- The
booksmethod returns the entire list of books. - The
bookmethod takes anidargument as a keyword parameter and returns the book that matches the givenid. - Arguments are accessed directly as method parameters, following Ruby's keyword argument syntax.
Running the Sinatra Server with Updated Schema and Resolvers
To see our updated schema and resolvers in action, we need to define our GraphQL schema class and set up Sinatra to handle GraphQL requests.
First, define the schema class:
Next, set up the Sinatra server to handle GraphQL requests:
Finally, start the Sinatra server. Create a file named main.rb with all the code above and add:
When you run this code with ruby main.rb, you should see the following output:
This indicates that your server is running and ready to handle queries.
Making GraphQL Queries with Arguments
Now, let's make some GraphQL queries that include arguments using Ruby's Net::HTTP library.
Create a new file named run.rb with the following code:
Explanation:
- We define two GraphQL queries: One to fetch all books and another to fetch a specific book by its
id. - We create the request object using
Net::HTTP::Post.new(url), then set theContent-Typeheader and request body as separate steps. This gives us more control over the request configuration. - We use
Net::HTTP.startwith a block to manage HTTP connections. The start method with a block automatically handles opening and closing the connection, which is more efficient when making multiple requests and ensures proper cleanup even if an error occurs. - The
JSON.generatemethod converts Ruby hashes to JSON format. - The
JSON.parsemethod parses the JSON response back into Ruby data structures. - We use Ruby's
begin/rescueblock for error handling. - The server processes the queries and returns the requested data.
Output:
Lesson Summary
In this lesson, we expanded our knowledge of GraphQL by learning how to query with arguments. We:
- Defined a schema that supports arguments in queries using
graphql-ruby's class-based type definitions. - Created resolvers as methods within type classes to handle these queries.
- Set up a Sinatra server with the updated schema and resolvers.
- Made and executed GraphQL queries with arguments using Ruby's
Net::HTTPlibrary.
You should now proceed to the practice exercises to solidify your understanding of querying with arguments. In the next lesson, we will tackle more advanced features to further enhance your skills. Keep practicing and refining your knowledge!
