[Ruby] How to create a query using variables with GraphQL [Using Ruby on Rails]

4 minute read

Introduction

*This article is It is the added content of the previous article “Getting and displaying data from GraphQL API with Rails”. If you don’t mind, I would appreciate it if you read from the previous article (Direct Marketing

In the GraphQL query writing introduced in the previous article I’m sure some of you have wondered, “How can I use variables in a query?”

In the case of I I wanted to pass the data acquired with the REST API to the GraphQL API, so How can I include variables in my query? I had the question.

Then, if you go to “Pass variable to GraphQL query” or googling After all, easy-to-understand articles do not hit! __

So, this time too, it was easy for beginners to understand (I am a beginner… I will explain how to use variables in GraphQL queries.

Static query

This time, I will explain using the following query as an example.

query {
    repositoryOwner(login:"github username") {
        repositories(last:5){
            nodes {
                name
            }
        }
    }
}

If you specify your github username, It is a query that retrieves 5 new ones from the specified user’s repository.

However, it is not a dynamic query in this state. If you write the user name directly in the query, you will only get the repository for that user.

For example, if you enter your github username, When making an application that displays the latest 5 of the user’s repository I can not respond with this query. How can I make this query a dynamic query?

To make this query a dynamic query You need to understand how to write a query called variables.

What is #variables “Variables” are variables when translated into Japanese. ~~ (I can’t say that I did some research to write this article or noticed it)-~

Here, I will explain how to write these variables. If you add variables to the above query and rewrite it, it will be as follows.

query ($user: String!) {
    repositoryOwner(login:$user) {
        repositories(last:5){
            nodes {
                name
            }
        }
    }
}

- -variables--
{
  "user": "username"
}

The difference between before rewriting and after rewriting is that the first and second lines are three places under variables.

First, from the first line,

query ($user: String!) {

Although the description of $user: String! is added after query, This writes Arguments, GraphQL arguments and argument types. Also, by writing “$” before the argument user, Variables written outside the query are used as arguments in the query.

Then the second line

repositoryOwner(login:$user) {

Before rewriting, I was writing the github user name directly in the login value. I think it has changed to $user. This is the data passed in the argument A dynamic query is made by giving it as the value of login.

Finally, the description under variables

{
  "user": "username"
}

In GraphiQL, there is a space to write Variables under the query editor. In addition to the description of the first line and the second line, which was explained earlier when describing it there It will be available in the query as the variable user.

…This is good for GraphiQL, but It’s a little different when used in Rails apps.

How to write Variables in Rails

That’s why it’s written in Rails.

This time, I will explain it by adding it to the newly created application with scaffold. The final form is “Enter the name of a github user and display the 5 latest repositories for that user” I will create.

*The introduction part is omitted, but it is created according to the following flow. ① Application creation ② Generate the required model with scaffold (only user is generated this time) ④ Database related creation, migrate ③ Introducing and setting graphql-client referring to the previous article

After installation, add the following to the controller.

controllers/users_controller.rb


class UsersController <ApplicationController
...abridgement...
  Query = GqlTest(your app name)::Client.parse <<-GRAPHQL
  query ($user: String!) {
    repositoryOwner(login: $user) {
        repositories(last:5){
            nodes {
                name
            }
        }
    }
}
    GRAPHQL

  def show
    username = @user.name
    @works = result(user: username).data.repository_owner.repositories.nodes
  end

···abridgement···
  private
  def result(variables = {})
    response = GqlTest(*your application name)::Client.query(Query, variables: variables)
  end
end

If you explain the added code The query is Query = GqlTest(your app name)::Client.parse «-GRAPHQL It is OK if you write the query created earlier after the code of.

controllers/users_controller.rb


Query = GqlTest(your app name)::Client.parse <<-GRAPHQL
  query ($user: String!) {
    repositoryOwner(login: $user) {
        repositories(last:5){
            nodes {
                name
            }
        }
    }
}

What I added in the show action With the code to bring the user name registered with the new action as @user.name and store it in username It is a code to retrieve the result data with the username as an argument. user: username is Described in the Variables space under the GraphiQL query editor.

controllers/users_controller.rb


def show
    username = @user.name
    @works = result(user: username).data.repository_owner.repositories.nodes
end

In the result method under private, I added the following. The difference from the previous article is that after the query variables: variables Variables can be used by describing. For a detailed explanation of this part, see the official reference of graphql-client. please confirm. (Official reference: https://github.com/github/graphql-client ).

controllers/users_controller.rb


private
  def result(variables = {})
    response = GqlTest(*your application name)::Client.query(Query, variables: variables)
  end
end

And finally, change the show.html.erb of the view to complete.

Ruby:views/show.html.erb


<% @works.each do |work|%>
   <p><%= work.name %></p>
<% end %>

Please add the above code to your favorite place of show.html.erb created with scaffold I think it will be displayed.

![Screenshot 2020-08-28 23.24.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601315/f64ca054-2328-ba47-bf09-(cb2caac179f1.png)

If it can be displayed as above, it is complete!

Thank you for your hard work!

(This time too, I wrote it in the middle of the night, so there may be various typographical errors…)