GraphQL-クエリ

GraphQL操作は、読み取り操作または書き込み操作のいずれかです。GraphQLクエリは値の読み取りまたはフェッチに使用され、ミューテーションは値の書き込みまたは投稿に使用されます。いずれの場合も、操作はGraphQLサーバーが解析し、特定の形式のデータで応答できる単純な文字列です。モバイルおよびWebアプリケーションで通常使用される一般的な応答形式はJSONです。

クエリを定義する構文は次のとおりです-

//syntax 1
query query_name{ someField }

//syntax 2
{ someField }

以下はクエリの例です-

//query with name myQuery
query myQuery{
   greeting
}

// query without any name
{
   greeting
}

上記の例から、queryキーワードがオプションであることは明らかです。

GraphQLクエリは、データのオーバーフェッチを減らすのに役立ちます。Restful APIとは異なり、GraphQLを使用すると、ユーザーはサーバーからフェッチする必要のあるフィールドを制限できます。これは、クエリが小さくなり、ネットワーク上のトラフィックが少なくなることを意味します。これにより、応答時間が短縮されます。

図1-カスタムフィールドを使用した学生モデルのクエリ

この例では、jsonファイルに保存されている学生のセットがあります。各学生モデルには、firstName、lastName、idなどのフィールドがありますが、fullNameはありません。ここでは、すべての学生のfullNameを取得するクエリを作成する方法について説明します。このために、両方のスキーマリゾルバーでfullNameフィールドを作成する必要があります。

以下の手順を使用して、この図を作成する方法を見てみましょう。

ステップ1-プロジェクトに必要な依存関係をダウンロードしてインストールする

名前の付いたフォルダを作成します query-app。ディレクトリを次のように変更しますquery-appターミナルから。後で、環境設定の章で説明されている手順3〜5に従います。

ステップ2-スキーマを作成する

追加 schema.graphql プロジェクトフォルダquery-appにファイルし、次のコードを追加します-

type Query {
   greeting:String
   students:[Student]
   studentById(id:ID!):Student
}

type Student {
   id:ID!
   firstName:String
   lastName:String
   fullName:String 
}

にはfullNameフィールドがないことに注意してくださいstudents.jsonファイル。ただし、クエリを介して学生のフルネームを取得する必要があります。fullNameが、この場合には、データ・ソースでは使用できませんカスタムフィールドになります。

ステップ3-リゾルバーを作成する

ファイルを作成する resolvers.js プロジェクトフォルダに次のコードを追加します-

const db = require('./db')
const Query = {
   //resolver function for greeting
   greeting:() => {
      return "hello from  TutorialsPoint !!!"
   },
   
   //resolver function for students returns list
   students:() => db.students.list(),

   //resolver function for studentbyId
   studentById:(root,args,context,info) => {
      //args will contain parameter passed in query
      return db.students.get(args.id);
   }
}

//for each single student object returned,resolver is invoked

const Student = {
   fullName:(root,args,context,info) => {
      return root.firstName+":"+root.lastName
   }
}

module.exports = {Query,Student}

ステップ4-アプリケーションを実行する

作成する server.jsファイル。環境設定の章のステップ8を参照してください。ターミナルでコマンドnpmstartを実行し ます。サーバーは9000ポートで稼働します。ここでは、アプリケーションをテストするためのクライアントとしてGraphiQLを使用します。

ブラウザを開き、URLを入力します http://localhost:9000/graphiql。エディタに次のクエリを入力します-

{
   students{
      id
      fullName
   }
}

クエリに対する応答を以下に示します-

{
   "data": {
      "students": [
         {
            "id": "S1001",
            "fullName": "Mohtashim:Mohammad"
         },
         
         {
            "id": "S1002",
            "fullName": "Kannan:Sudhakaran"
         },
         
         {
            "id": "S1003",
            "fullName": "Kiran:Panigrahi"
         }
      ]
   }
}

作成する server.js 次のコードを追加します-

const bodyParser = require('body-parser');
const cors = require('cors');
const express = require('express');

const db = require('./db');
const port = 9000;
const app = express();

//loading type definitions from schema file
const fs = require('fs')
const typeDefs = fs.readFileSync('./schema.graphql',{encoding:'utf-8'})

//loading resolvers
const resolvers = require('./resolvers')

//binding schema and resolver
const {makeExecutableSchema} = require('graphql-tools')
const schema = makeExecutableSchema({typeDefs, resolvers})

//enabling cross domain calls and form post
app.use(cors(), bodyParser.json());

//enabling routes
const  {graphiqlExpress,graphqlExpress} = require('apollo-server-express')
app.use('/graphql',graphqlExpress({schema}))
app.use('/graphiql',graphiqlExpress({endpointURL:'/graphql'}))

//registering port
app.listen(port, () => console.info(`Server started on port ${port}`));

ターミナルでコマンドnpmstartを実行します。サーバーは9000ポートで稼働します。ここでは、アプリケーションをテストするためのクライアントとしてGraphiQLを使用します。

ブラウザを開き、URLを入力します http://localhost:9000/graphiql。エディタに次のクエリを入力します-

{
   students{
      id
      fullName
   }
}

クエリに対する応答を以下に示します-

{
   "data": {
      "students": [
         {
            "id": "S1001",
            "fullName": "Mohtashim:Mohammad"
         },
         {
            "id": "S1002",
            "fullName": "Kannan:Sudhakaran"
         },
         {
            "id": "S1003",
            "fullName": "Kiran:Panigrahi"
         }
      ]
   }
}

図2-ネストされたクエリ

学生の詳細と大学の詳細を取得するためのネストされたクエリを作成しましょう。同じプロジェクトフォルダで作業します。

ステップ1-スキーマを編集する

スキーマファイルにはすでにstudentフィールドがあります。フィールドカレッジを追加して、そのタイプを定義しましょう。

type College {
   id:ID!
   name:String
   location:String
   rating:Float
}

type Student {
   id:ID!
   firstName:String
   lastName:String
   fullName:String
   college:College
}

ステップ2-resolver.jsを変更します

以下のように大学のレゾルバ関数を追加する必要があります。大学のリゾルバ関数は、返された各学生オブジェクトに対して実行されます。この場合のresolverのrootパラメーターにはstudentが含まれます。

const Student = {
   fullName:(root,args,context,info) => {
      return root.firstName+":"+root.lastName
   },
   college:(root) => {
      return db.colleges.get(root.collegeId);
   }
}
module.exports = {Query,Student}

リゾルバーは、collegeコレクションのgetメソッドを呼び出し、collegeIdを渡すことにより、各学生の大学を返します。私たちはcollegeIdを通じてStudentとCollegeの間に関連関係があります

ステップ3-アプリケーションをテストする

ターミナルウィンドウを開き、プロジェクトフォルダに移動します。コマンド-npmstartを入力します。ブラウザを起動し、URLを入力しますhttp://localhost:9000/graphiql

GraphiQLウィンドウに次のクエリを入力します-

{
   students{
      id
      firstName
      college {
         id
         name
         location
         rating
      }
   }
}

クエリに対する応答は次のとおりです-

{
   "data": {
      "students": [
         {
            "id": "S1001",
            "firstName": "Mohtashim",
            "college": {
               "id": "col-102",
               "name": "CUSAT",
               "location": "Kerala",
               "rating": 4.5
            }
         },
         
         {
            "id": "S1002",
            "firstName": "Kannan",
            "college": {
               "id": "col-101",
               "name": "AMU",
               "location": "Uttar Pradesh",
               "rating": 5
            }
         },
         
         {
            "id": "S1003",
            "firstName": "Kiran",
            "college": {
               "id": "col-101",
               "name": "AMU",
               "location": "Uttar Pradesh",
               "rating": 5
            }
         }
      ]
   }
}

クエリ変数とは何ですか?

クエリに渡される動的な値がある場合は、変数を使用してこれらの動的な値を表します。したがって、クエリはクライアントアプリケーションで再利用できます。

クエリ変数を理解するための簡単なアプリケーションを作成しましょう。

ステップ1-スキーマファイルを編集する

文字列パラメータを受け取り、文字列を返すsayHelloフィールドを追加します。名前の値は、クライアントアプリケーションで動的になります。

type Query {
   sayHello(name:String!):String
}

ステップ2-resolver.jsファイルを編集する

以下のパラメータをとるsayHelloリゾルバを追加します-

sayHello:(root,args,context,info) => `Hi ${args.name} GraphQL server says Hello to you!!`

ステップ3-GraphiQLでクエリ変数を宣言する

変数は、$とそれに続く変数名で宣言されます。例:$ myname_Variable。

$ myname_Variableが宣言されたら、名前付きクエリ構文で使用する必要があります。クエリmyQueryは文字列値を受け取り、以下に示すようにそれをsayHelloに渡します-

query myQuery($myname_Variable:String!) {
   sayHello(name:$myname_Variable)
}

GraphiQLクライアントの[クエリ変数]セクションで、$ myname_Variableの値をJSONオブジェクトとして設定します。

{
   "myname_Variable": "Mohtashim"
}

上記のコードの出力は次のとおりです-

{
   "data": {
      "sayHello": "Hi Mohtashim GraphQL server says Hello to you!!"
   }
}

列挙型でクエリ変数を使用する方法

フィールドパラメータがであるときにクエリ変数を使用する方法を見てみましょう enum type

ステップ1-schema.graphqlファイルを編集する

enum ColorType {
   RED
   BLUE
   GREEN
}

type Query {
   setFavouriteColor(color:ColorType):String
}

setFavouriteColorの関数は、入力として列挙を受け取り、文字列値を返します。

ステップ2-resolvers.jsファイルを編集する

リゾルバー関数setFavouriteColorrootargsを取ります。実行時に関数に渡される列挙値には、argsパラメーターを介してアクセスできます。

setFavouriteColor:(root,args) => {
   return  "Your Fav Color is :"+args.color;
}

ステップ3-GraphiQLでクエリ変数を宣言する

クエリの名前は query_to_setColorこれは、ColorTypeのcolor_variableという名前の変数を取ります。この変数はメソッドsetFavouriteColorに渡されます。

query query_to_setColor($color_variable:ColorType) {
   setFavouriteColor(color:$color_variable)
}

GraphiQLのクエリ変数セクションに、次のコードを入力します-

{
   "color_variable":"RED"
}

応答を以下に示します-

{
   "data": {
      "setFavouriteColor": "Your Fav Color is: RED"
   }
}