13 Oracle REST Data ServicesでのGraphQL

この項では、Oracle REST Data ServicesのGraphQL機能を紹介します。

Oracle REST Data ServicesのGraphQL機能では、GraphQL問合せを使用してOracle REST Data Services対応スキーマからデータをフェッチできます。

トピック:

13.1 GraphQLの用語

この項では、この項で使用する一般的な用語について説明します。

この項で使用する一般的な用語を次に示します。

  • GraphQLスキーマ定義言語(SDL):簡単にGraphQLスキーマ言語と呼ばれることもあります。これは、スキーマを定義できる、構文が単純な言語です。
  • スキーマ: GraphQLのコンテキストにおけるスキーマとは、GraphQLタイプの集合のことを指しています。
  • タイプ: サービスからフェッチできる、一種のオブジェクトを表します。Oracle REST Data Servicesでの、REST対応の表またはビュー・オブジェクトそれぞれが、1つのGraphQLタイプとなります。
  • フィールド: GraphQLタイプには、問合せでフェッチできる一連のフィールドが含まれています。Oracle REST Data Servicesでの表またはビュー・オブジェクトの各列が、1つのフィールドとなります。

13.2 Oracle REST Data ServicesでのGraphQLの有効化

この項では、GraphQLを有効にする方法を説明します。

GraphQLを有効にするには、Javaスクリプト・コンポーネントが有効になっているGraalVMランタイム環境でOracle REST Data Servicesを実行する必要があります。

関連項目:

システム要件

13.3 GraphQLに対するオブジェクトの有効化

この項では、GraphQLに対してオブジェクトを有効にする方法を説明します。

Oracle REST Data Services対応スキーマの、REST対応の表またはビューには、GraphQL問合せによってアクセスできます。REST対応オブジェクトをGraphQLタイプにマップするには、1つ以上の主キーがそのオブジェクトに関連付けられている必要があります。この条件を満たしていない場合は、問合せで取得されたオブジェクトが一意であり結合から生じた複製ではないことを保証するために、ROWID擬似列が使用されます。

ノート:

識別子としてのROWIDの使用には、いくつか制限事項があります。
GraphQLのエンドポイントの構文:
http://<HOST>:<PORT>/ords/<Schema>/_/graphql

ノート:

この機能を使用できるのは、Oracle REST Data Services対応スキーマの場合のみです。

13.3.1 保護されたREST対応オブジェクトへのアクセス

ユーザーが定義した権限またはロールで、認可が必要なREST対応オブジェクトを保護できます。たとえば、REST対応オブジェクトがautoRESTデフォルト権限またはロールによって保護されている場合、そのオブジェクトにアクセスするには、次のロールおよび権限が必要です。
  • oracle.dbtools.autorest.any.schema
  • oracle.dbtools.role.autorest.<SCHEMANAME>.<OBJECTNAME>
  • oracle.dbtools.autorest.privilege.<SCHEMANAME>.<OBJECTNAME>
つまり、保護されたオブジェクトにアクセスできるようにするには、GraphQLリクエストに、適切な認可が必要です。この保護は、前述の自動REST権限およびロールにかぎりません。これは、GraphQL機能でURIパターン保護が適用されるためです。

13.4 GraphQL問合せの使用によるオブジェクトへのアクセス

この項では、表とビューをREST対応にした後にそれらの表とビューに対してGraphQL問合せを使用する例を示します。

この項では、次の例について説明します。

13.4.1 GraphQLスキーマの取得

GraphQLスキーマは、自動生成され、REST対応ユーザー・データベース・スキーマのREST対応オブジェクト(表とビュー)を含んでいます。

生成されたスキーマには、次の内容が含まれています。
  • 列がフィールドとして表されている、GraphQLタイプとして表された各REST対応オブジェクト、およびそれらのオブジェクト間の関係。
  • REST対応オブジェクトすべてのリゾルバ
  • サポートされているデータ型

このGraphQLスキーマを取得するには、次の問合せを実行します。

構文:
GET 'http://<HOST>:<PORT>/ords/<Schema>/_/graphql'
問合せの例:
GET 'http://localhost:8080/ords/hr/_/graphql'

レスポンス:

{"schemaName":"HR","description":"the SDL representation of the 'HR' GraphQL Schema","SDL":"type Query {  \"\"\"Generic resolver for EMPLOYEES type.\"\"\"\n 
      employees(primaryKey: JSON, where: JSON, sort: JSON, limit: Int, offset: Int):
      [EMPLOYEES]\n\n  \"\"\"Generic resolver for COUNTRIES type.\"\"\"\n 
      countries(primaryKey: JSON, where: JSON, sort: JSON, limit: Int, offset: Int):
      [COUNTRIES]\n}\n\n\"\"\"\nThe 'Date' scalar type represents date values as specified by the
      ISO 8601 format in UTC time zone (YYYY-MM-DDThh:mm:ssZ).\n\"\"\"\nscalar
      Date\n\n\"\"\"\nThe `Float` scalar type represents signed double-precision fractional
      values as specified by [IEEE 754](https://en.wikipedia.org/wiki/IEEE_floating_point).\n\"\"\"\nscalar
      Float\n\n\"\"\"\nThe `Int` scalar type represents non-fractional signed whole numeric
      values. Int can represent values between -(2^31) and 2^31 - 1.\n\"\"\"\nscalar
      Int\n\n\"\"\"\nThe `JSON` scalar type represents JSON values as specified by [ECMA-404](http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf).\n\"\"\"\nscalar
      JSON\n\n\"\"\"\nThe `String` scalar type represents textual data, represented as UTF-8
      character sequences. The String type is most often used by GraphQL to represent free-form
      human-readable text.\n\"\"\"\nscalar String\n\ntype COUNTRIES {\n  country_id: String!\n 
      country_name: String\n  region_id: Int\n}\n\ntype EMPLOYEES {\n  employee_id: Int!\n 
      manager_id: Int\n  phone_number: String\n  commission_pct: Float\n  department_id: Int\n 
      salary: Float\n  first_name: String\n  email: String!\n  job_id: String!\n  hire_date:
      Date!\n  last_name: String!\n\n  \"\"\"\n  The relationship between the EMPLOYEES type
      and the EMPLOYEES type on EMPLOYEES.MANAGER_ID = EMPLOYEES.EMPLOYEE_ID\n  \"\"\"\n 
      manager_id_employees(primaryKey: JSON, where: JSON, sort: JSON, limit: Int, offset: Int):
      [EMPLOYEES]\n\n  \"\"\"\n  The relationship between the EMPLOYEES type and the EMPLOYEES
      type on EMPLOYEES.EMPLOYEE_ID = EMPLOYEES.MANAGER_ID\n  \"\"\"\n 
      employees_manager_id(primaryKey: JSON, where: JSON, sort: JSON, limit: Int, offset: Int):
      [EMPLOYEES]\n}"}

13.4.2 単純な問合せ

単純な問合せにより、GraphQLスキーマ内に存在するタイプ内のデータを取得します。

この問合せ例では、HRスキーマからemployeesタイプにあるemployee_idfirst_namelast_namejob_idおよびsalaryをフェッチします。
query Employees {
  employees {
    employee_id
    first_name
    last_name
    job_id
    salary
  }
}

cURLコマンドの例:

curl --location 'http://localhost:8080/ords/hr/_/graphql' \
--header 'Content-Type: application/json' \
--data '{
    "query": "{employees { employee_id first_name last_name job_id salary }}"
}'

レスポンス:

{
  "data": {
    "employees": [
      {
        "employee_id": 100,
        "first_name": "Steven",
        "last_name": "King",
        "job_id": "AD_PRES",
        "salary": 24000
      },
      {
        "employee_id": 101,
        "first_name": "Neena",
        "last_name": "Kochhar",
        "job_id": "AD_VP",
        "salary": 17000
      },
      {
        "employee_id": 103,
        "first_name": "Alexander",
        "last_name": "Hunold",
        "job_id": "IT_PROG",
        "salary": 9000
      },
      {
        "employee_id": 104,
        "first_name": "Bruce",
        "last_name": "Ernst",
        "job_id": "IT_PROG",
        "salary": 6000
      },
      {
        "employee_id": 105,
        "first_name": "David",
        "last_name": "Austin",
        "job_id": "IT_PROG",
        "salary": 4800
      },
    ...
}

13.4.3 結合問合せ

結合問合せにより、GraphQLスキーマ内に存在する複数の既存のタイプの間の1つ以上の関係からデータを取得します。

例1:

次の問合せでは、事業所に関連付けられている市区町村すべてと、各市区町村にある部門、およびそれらの各部門で働く従業員をフェッチします。
query Locations{
  locations{
    city
    departments_location_id{
      department_name
      employees_department_id{
        first_name
        last_name
        salary
      }
    }
  }
}
cURLコマンドの例:
curl --location 'http://localhost:8080/ords/hr/_/graphql' \
--header 'Content-Type: application/json' \
--data '{
    "query": "query Locations{ locations{ city departments_location_id{ department_name employees_department_id{first_name last_name salary} } } }"
}'
レスポンス:
{
  "data": {
    "locations": [
      {
        "city": "Seattle",
        "departments_location_id": [
          {
            "department_name": "Executive",
            "employees_department_id": [
              {
                "first_name": "Steven",
                "last_name": "King",
                "salary": 24000
              },
              {
                "first_name": "Neena",
                "last_name": "Kochhar",
                "salary": 17000
              },
              {
                "first_name": "Lex",
                "last_name": "De Haan",
                "salary": 17000
              }
            ]
          },
          {
            "department_name": "Finance",
            "employees_department_id": [
              {
                "first_name": "Nancy",
                "last_name": "Greenberg",
                "salary": 12000
              },
              {
                "first_name": "Daniel",
                "last_name": "Faviet",
                "salary": 9000
              },
              {
                "first_name": "John",
                "last_name": "Chen",
                "salary": 8200
              },
              {
                "first_name": "Ismael",
                "last_name": "Sciarra",
                "salary": 7700
              },
              {
                "first_name": "Jose Manuel",
                "last_name": "Urman",
                "salary": 7800
              },
              {
                "first_name": "Luis",
                "last_name": "Popp",
                "salary": 6900
              }
            ]
          },
          {
            "department_name": "Purchasing",
            "employees_department_id": [
              {
                "first_name": "Den",
                "last_name": "Raphaely",
                "salary": 11000
              },
              {
                "first_name": "Alexander",
                "last_name": "Khoo",
                "salary": 3100
              },
              {
                "first_name": "Shelli",
                "last_name": "Baida",
                "salary": 2900
              },
              {
                "first_name": "Sigal",
                "last_name": "Tobias",
                "salary": 2800
              },
              {
                "first_name": "Guy",
                "last_name": "Himuro",
                "salary": 2600
              },
              {
                "first_name": "Karen",
                "last_name": "Colmenares",
                "salary": 2500
              }
            ]
          },
          {
            "department_name": "Administration",
            "employees_department_id": [
              {
                "first_name": "Jennifer",
                "last_name": "Whalen",
                "salary": 4400
              }
            ]
          },
          {
            "department_name": "Accounting",
            "employees_department_id": [
              {
                "first_name": "Shelley",
                "last_name": "Higgins",
                "salary": 12000
              },
              {
                "first_name": "William",
                "last_name": "Gietz",
                "salary": 8300
              }
            ]
          },
          {
            "department_name": "IT Support",
            "employees_department_id": []
          },
          {
            "department_name": "Operations",
            "employees_department_id": []
          },
          {
            "department_name": "Payroll",
            "employees_department_id": []
          },
          {
            "department_name": "Construction",
            "employees_department_id": []
          },
          {
            "department_name": "Government Sales",
            "employees_department_id": []
          },
          {
            "department_name": "Retail Sales",
            "employees_department_id": []
          },
          {
            "department_name": "Contracting",
            "employees_department_id": []
          },
          {
            "department_name": "Recruiting",
            "employees_department_id": []
          },
          {
            "department_name": "Control And Credit",
            "employees_department_id": []
          },
          {
            "department_name": "NOC",
            "employees_department_id": []
          },
          {
            "department_name": "Treasury",
            "employees_department_id": []
          },
          {
            "department_name": "Manufacturing",
            "employees_department_id": []
          },
          {
            "department_name": "Corporate Tax",
            "employees_department_id": []
          },
          {
            "department_name": "IT Helpdesk",
            "employees_department_id": []
          },
          {
            "department_name": "Shareholder Services",
            "employees_department_id": []
          },
          {
            "department_name": "Benefits",
            "employees_department_id": []
          }
        ]
      }
    ]
  }
}

例2:

次の問合せ例では、HRスキーマ内のすべての従業員と、それらの従業員が勤務している部門をフェッチします。
query Employees {
    employees {
        employee_id
        first_name
        last_name
        departments_department_id {
            department_id
            department_name
        }
    }
}
cURLコマンドの例:
curl --location 'http://localhost:8080/ords/hr/_/graphql' \
--header 'Content-Type: application/json' \
--data '{
    "query": "{employees { employee_id first_name last_name departments_department_id{ department_id department_name } }}"
}'

レスポンス:

{
    "data": {
        "employees": [
            {
                "employee_id": 200,
                "first_name": "Jennifer",
                "last_name": "Whalen",
                "departments_department_id": [
                    {
                        "department_id": 10,
                        "department_name": "Administration"
                    }
                ]
            },
            {
                "employee_id": 201,
                "first_name": "Michael",
                "last_name": "Hartstein",
                "departments_department_id": [
                    {
                        "department_id": 20,
                        "department_name": "Marketing"
                    }
                ]
            },
            {
                "employee_id": 202,
                "first_name": "Pat",
                "last_name": "Fay",
                "departments_department_id": [
                    {
                        "department_id": 20,
                        "department_name": "Marketing"
                    }
                ]
            },...
        ]
    }
}

ノート:

GraphQLのネストの深さは、5レベルまでに制限されています。ネストされた結合が5つより多い問合せでは、エラーが返されます。

13.4.3.1 オブジェクト間の相互関係

この項では、相互関係の例について説明します。

表またはビューには相互関係が含まれている場合があります。GraphQLを使用してそのデータを問い合せることができます。

次に、HRスキーマ内の相互関係の例を示します。

employees表では、manager_id列とemployee_id列の間に制約が定義されています。

次の問合せ例では、HRスキーマ内のすべての従業員を、それぞれのマネージャとともにフェッチします。
query Employees {
    employees {
        employee_id
        first_name
        last_name
        manager_id
        manager_id_employees {
            first_name
            last_name
            employee_id
        }
    }
}
cURLコマンドの例:
curl --location 'http://localhost:8080/ords/hr/_/graphql' \
--header 'Content-Type: application/json' \
--data '{
    "query": "{ employees { employee_id first_name last_name  manager_id employees_manager_id{ first_name last_name employee_id } } }"
}'
レスポンス:
{
  "data": {
    "employees": [
      {
        "employee_id": 101,
        "first_name": "Neena",
        "last_name": "Kochhar",
        "manager_id": 100,
        "employees_manager_id": [
          {
            "first_name": "Steven",
            "last_name": "King",
            "employee_id": 100
          }
        ]
      },
      {
        "employee_id": 114,
        "first_name": "Den",
        "last_name": "Raphaely",
        "manager_id": 100,
        "employees_manager_id": [
          {
            "first_name": "Steven",
            "last_name": "King",
            "employee_id": 100
          },
          {
            "first_name": "Eleni",
            "last_name": "Zlotkey",
            "employee_id": 149
          }
        ]
      },
      {
        "employee_id": 120,
        "first_name": "Matthew",
        "last_name": "Weiss",
        "manager_id": 100,
        "employees_manager_id": [
          {
            "first_name": "Steven",
            "last_name": "King",
            "employee_id": 100
          },
          {
            "first_name": "John",
            "last_name": "Russell",
            "employee_id": 145
          },
          {
            "first_name": "Karen",
            "last_name": "Partners",
            "employee_id": 146
          }
        ]
      }
  }
}

13.5 問合せでのフィルタリングの例

この項では、REST対応の表やビューに対する問合せでのフィルタリングの例を示します。

問合せにおいてフィルタするには、パラメータ<filterName>: GraphQLJSONを含めます。ここでのGraphQLJSONは、リソースに適用するカスタム選択を表す、JSONのようなオブジェクトです。各フィルタには、それ固有の、事前定義済のGraphQLJSON構文があります。

13.5.1 サポートされているデータ型

この項では、フィルタでサポートされているデータ型をリストします。

データ型 説明
String stringスカラー型は、UTF-8文字列として表される、テキスト・データを表します。string型は、GraphQLで、判読可能な自由形式のテキストを表すために最もよく使用されます。
Int intスカラー型は、非小数の符号付き整数値を表します。intでは、-(2^31)から2^31 - 1までの値を表すことができます。
Float floatスカラー型は、IEEE 754で指定されている、符号付き倍精度小数値を表します。
Date dateスカラー型は、UTCタイム・ゾーンでのISO 8601形式で指定されている日付値(YYYY-MM-DDThh:mm:ssZ)を表します。
Timestamp timestampスカラー型は、UTCタイム・ゾーンでのISO 8601形式で指定されているタイムスタンプ値(YYYY-MM-DDThh:mm:ss.sssZ)を表します。
Boolean booleanスカラー型は、trueまたはfalseを表します。

13.5.2 主キーによるフィルタリング

主キーによるフィルタリングでは、データを、それを識別するキー値(1つまたは複数)を指定することで取得できます。

主キー構文:

value = String | Int | Float | Date | Timestamp
primaryKeyPair = <fieldName> : <value>
primaryKeyExp = { primaryKeyPair1, ... , primaryKeyPairN }
次の問合せには、employee_idフィールドを100に限定するフィルタが含まれています。
query {
  employees(primaryKey: {employee_id: 100}){
    employee_id
    first_name
    last_name
    job_id
    salary
  }
}
cURLコマンドの例:
curl --location 'http://localhost:8080/ords/hr/_/graphql' \
--header 'Content-Type: application/json' \
--data '{
    "query": "{ employees(primaryKey : {employee_id :100}) { first_name last_name department_id job_id } } "
}'

レスポンス:

{
  "data": {
    "employees": [
      {
        "first_name": "Steven",
        "last_name": "King",
        "department_id": 90,
        "job_id": "AD_PRES"
      }
    ]
  }
}
13.5.2.1 複合主キーによるフィルタリング

主キーによるフィルタリングでは、フィルタに主キーのリストを追加することで複合主キーがある表からデータを取得できます。

query {
  compositeTable(primaryKey: { <fieldName> : <value>, <fieldName> : <value>}){
    data
  }
}

13.5.3 Whereフィルタ

where条件を使用してフィルタすると、データを問い合せて、リクエストしたタイプに存在するフィールドが満たしている必要がある有効な条件(1つまたは複数)を指定できます。

Whereフィルタ構文:

fieldName = stringvalue = String | Int | Float | Date | Timestamp  operator = eq | neq | gt | lt | gte | lte | like | nlike | in | nin | btwn | nbtwn
          | nullbooleanOperator = and | orvalidFilter = { <fieldName> : { <operator> : <value> } }booleanExp = { <booleanOperator> : [ <ValidFilter1 | BoleanExp1>, ..., <ValidFilterN |
        BoleanExpN> ] }whereExp = { where : <validFilter | booleanExp> }

表13-1 サポートされている演算子

演算子 GraphQLJSON構文 説明 サポートされているデータ型
= { column : { eq : value } } 等価 String | Int | Float | Date | Timestamp
!=, <> { column : { neq : value } } 非等価 String | Int | Float | Date | Timestamp
> { column : { gt : value } } より大きい String | Int | Float | Date | Timestamp
< { column : { lt : value } } より小さい String | Int | Float | Date | Timestamp
>= { column : { gte : value } } 以上 String | Int | Float | Date | Timestamp
<= { column : { lte : value } } 以下 String | Int | Float | Date | Timestamp
LIKE { column : { like : pattern } } パターン照合に使用する演算子 文字列
NOT LIKE { column : { nlike : pattern } } パターン照合に使用する演算子 文字列
IN { column : { in : [value1_, ... , value_n ] } } 値リスト内のいずれかの値と等しい String | Int | Float | Date | Timestamp
NOT IN { column : { nin : [value_1, ... ,value_n] } } 値リスト内のどの値とも等しくない String | Int | Float | Date | Timestamp
BETWEEN { column : { btwn : [value_1, value_2] } } >= nかつ<= yと等しい String | Int | Float | Date | Timestamp
NOT BETWEEN { column : { nbtwn : [value_1, value_2] } } >= nかつ<= yと等しくない String | Int | Float | Date | Timestamp
IS NULL { column : { null: [ Boolean ] } } NULLかどうかのテスト ブール値
OR
{ or : [ 
{ GraphQL expression 1 }
...,
{ GraphQL expression n }
] }
論理演算子。いずれかの式がtrueの場合はtrueを返します。 該当なし
NOT { NOT : { GraphQL式}} 論理演算子。対象となる式の論理値を否定します。 該当なし
AND
{ and : [ 
{ GraphQL expression 1 },
....,
{ GraphQL expression n }
] }
論理演算子。両方の式がtrueの場合はtrueを返します。 該当なし
13.5.3.1 例: 等号(eq)演算子

次の問合せには、job_idフィールドをIT_PROGに限定するフィルタが含まれています。

query {
  employees(where : {job_id: {eq : "IT_PROG"}}){    
    employee_id
    first_name
    last_name
    job_id
    salary
   }
}
cURLコマンドの例:
curl --location 'http://localhost:8080/ords/hr/_/graphql' \
--header 'Content-Type: application/json' \
--data '{
    "query": "{ employees(where : {job_id : {eq :\"IT_PROG\"}}) { employee_id first_name last_name job_id salary } } "
}'

レスポンス:

{
    "data": {
        "employees": [
            {
                "employee_id": 103,
                "first_name": "Alexander",
                "last_name": "Hunold",
                "job_id": "IT_PROG",
                "salary": 9000
            },
            {
                "employee_id": 104,
                "first_name": "Bruce",
                "last_name": "Ernst",
                "job_id": "IT_PROG",
                "salary": 6000
            },
            {
                "employee_id": 105,
                "first_name": "David",
                "last_name": "Austin",
                "job_id": "IT_PROG",
                "salary": 4800
            },
            {
                "employee_id": 106,
                "first_name": "Valli",
                "last_name": "Pataballa",
                "job_id": "IT_PROG",
                "salary": 4800
            },
            {
                "employee_id": 107,
                "first_name": "Diana",
                "last_name": "Lorentz",
                "job_id": "IT_PROG",
                "salary": 4200
            }
        ]
    }
}
13.5.3.2 例: より大(>)演算子および日付データ型

次の問合せには、hire_dateフィールドを01 Jan 2006より大きい値に限定するフィルタが含まれています。

query {
  employees(where : { hire_date : { gt : "2006-01-01T00:00:00Z" } } ){
    employee_id
    first_name
    last_name
    hire_date
  }
}
13.5.3.3 例: LIKE (like)演算子
次の問合せには、first_nameフィールドをパターンS%に一致する値に限定するフィルタが含まれています。
query {
  employees(where : { first_name : { like : "S%" } }){
    employee_id
    first_name
    last_name
  }
}
13.5.3.4 例: IN (in)演算子
次の問合せには、in演算子を使用してjob_idフィールドをIT_PROGまたはFI_ACCOUNTに限定するフィルタが含まれています。
query  {
  employees(where : { job_id : { in : ["IT_PROG", "FI_ACCOUNT"] } } ){
   employee_id
   first_name
   last_name
   job_id
   salary
  }
}
13.5.3.5 例: NOT (not)演算子
次の問合せには、給与フィールドを2000から10000までに制限した結果を否定するフィルタが含まれています。
query Employees {
  employees(where : {not : {salary : {btwn : [2000, 10000]}}}){
   employee_id
   first_name
   last_name
   job_id
   salary
  }
}

リクエスト:

curl --location 'http://localhost:8080/ords/hr/_/graphql' \
--header 'Content-Type: application/json' \
--data '{
    "query": "{employees(where : {not : {salary : {btwn : [2000, 10000]}}}){
               employee_id first_name last_name job_id salary } } "
}'

レスポンス:

{
  "data": {
    "employees": [
      {
        "employee_id": 100,
        "first_name": "Steven",
        "last_name": "King",
        "job_id": "AD_PRES",
        "salary": 24000
      },
      {
        "employee_id": 101,
        "first_name": "Neena",
        "last_name": "Kochhar",
        "job_id": "AD_VP",
        "salary": 17000
      },
      {
        "employee_id": 102,
        "first_name": "Lex",
        "last_name": "De Haan",
        "job_id": "AD_VP",
        "salary": 17000
      },
      {
        "employee_id": 108,
        "first_name": "Nancy",
        "last_name": "Greenberg",
        "job_id": "FI_MGR",
        "salary": 12008
      },
      {
        "employee_id": 114,
        "first_name": "Den",
        "last_name": "Raphaely",
        "job_id": "PU_MAN",
        "salary": 11000
      },
      {
        "employee_id": 145,
        "first_name": "John",
        "last_name": "Russell",
        "job_id": "SA_MAN",
        "salary": 14000
      },
      {
        "employee_id": 146,
        "first_name": "Karen",
        "last_name": "Partners",
        "job_id": "SA_MAN",
        "salary": 13500
      },
      {
        "employee_id": 147,
        "first_name": "Alberto",
        "last_name": "Errazuriz",
        "job_id": "SA_MAN",
        "salary": 12000
      },
      {
        "employee_id": 148,
        "first_name": "Gerald",
        "last_name": "Cambrault",
        "job_id": "SA_MAN",
        "salary": 11000
      },
      {
        "employee_id": 149,
        "first_name": "Eleni",
        "last_name": "Zlotkey",
        "job_id": "SA_MAN",
        "salary": 10500
      },
      {
        "employee_id": 162,
        "first_name": "Clara",
        "last_name": "Vishney",
        "job_id": "SA_REP",
        "salary": 10500
      },
      {
        "employee_id": 168,
        "first_name": "Lisa",
        "last_name": "Ozer",
        "job_id": "SA_REP",
        "salary": 11500
      },
      {
        "employee_id": 174,
        "first_name": "Ellen",
        "last_name": "Abel",
        "job_id": "SA_REP",
        "salary": 11000
      },
      {
        "employee_id": 201,
        "first_name": "Michael",
        "last_name": "Hartstein",
        "job_id": "MK_MAN",
        "salary": 13000
      },
      {
        "employee_id": 205,
        "first_name": "Shelley",
        "last_name": "Higgins",
        "job_id": "AC_MGR",
        "salary": 12008
      }
    ]
  }
}
13.5.3.6 例: AND (and)演算子
次の問合せには、job_idフィールドをIT_PROGに限定しsalaryフィールドを4000から6000までに限定するフィルタが含まれています。
query Employees {
  employees(where : { and : [
   {job_id : { eq : "IT_PROG" }},
   {salary : { btwn : [4000, 6000] }}
    ]}){
   employee_id
   first_name
   last_name
   job_id
   salary
  }
}

リクエスト:

query Employees {
  employees(where : { and : [
   {job_id : { eq : "IT_PROG" }},
   {salary : { btwn : [4000, 6000] }}
    ]}){
   employee_id
   first_name
   last_namecurl --location 'http://localhost:8080/ords/hr/_/graphql' \
--header 'Content-Type: application/json' \
--data '{
    "query": "{employees(where : { and : [  {job_id : { eq : \"IT_PROG\" }}, {salary : { btwn : [4000, 6000] }} ] }){
               employee_id first_name last_name job_id salary } } "
}'
   job_id
   salary
  }
}

レスポンス:

{
    "data": {
        "employees": [
            {
                "employee_id": 104,
                "first_name": "Bruce",
                "last_name": "Ernst",
                "job_id": "IT_PROG",
                "salary": 6000
            },
            {
                "employee_id": 105,
                "first_name": "David",
                "last_name": "Austin",
                "job_id": "IT_PROG",
                "salary": 4800
            },
            {
                "employee_id": 106,
                "first_name": "Valli",
                "last_name": "Pataballa",
                "job_id": "IT_PROG",
                "salary": 4800
            },
            {
                "employee_id": 107,
                "first_name": "Diana",
                "last_name": "Lorentz",
                "job_id": "IT_PROG",
                "salary": 4200
            }
        ]
    }
}
13.5.3.7 例: OR (or)演算子
次の問合せには、or演算子を使用してjob_idフィールドをIT_PROGまたはFI_ACCOUNTに限定するフィルタが含まれています。
query Employees {
  employees(where : { or : [
   {job_id : { eq : "IT_PROG" }},
   {job_id : { eq : "FI_ACCOUNT" }}
    ]}){
   employee_id
   first_name
   last_name
   job_id
   salary
  }
}
13.5.3.8 例: 子タイプでのWhereフィルタ

前の項で説明したフィルタはすべて、問合せ内のネストされたタイプに適用できます。それにより、単一の問合せにおいてフィルタできるフィールドの範囲を広がります。

次の問合せでは、job_idIT_PROGと等しい従業員のマネージャである、すべての従業員を取得します。
query{
  employees{
    employee_id
    first_name
    last_name
    job_id
    salary
    employees_manager_id(where : {job_id : {eq : "IT_PROG"}}){
      employee_id
    first_name
    last_name
    job_id
    salary
    }
  }
}

リクエスト:

curl --location 'http://localhost:8080/ords/hr/_/graphql' \
--header 'Content-Type: application/json' \
--data '{
    "query": "query{ employees{ employee_id first_name last_name job_id salary employees_manager_id( where : { job_id : 
    { eq :          \"IT_PROG\" } } ){employee_id first_name last_name job_id salary} } }"
}'

レスポンス:

{
  "data": {
    "employees": [
      {
        "employee_id": 102,
        "first_name": "Lex",
        "last_name": "De Haan",
        "job_id": "AD_VP",
        "salary": 17000,
        "employees_manager_id": [
          {
            "employee_id": 103,
            "first_name": "Alexander",
            "last_name": "Hunold",
            "job_id": "IT_PROG",
            "salary": 9000
          }
        ]
      },
      {
        "employee_id": 103,
        "first_name": "Alexander",
        "last_name": "Hunold",
        "job_id": "IT_PROG",
        "salary": 9000,
        "employees_manager_id": [
          {
            "employee_id": 104,
            "first_name": "Bruce",
            "last_name": "Ernst",
            "job_id": "IT_PROG",
            "salary": 6000
          },
          {
            "employee_id": 105,
            "first_name": "David",
            "last_name": "Austin",
            "job_id": "IT_PROG",
            "salary": 4800
          },
          {
            "employee_id": 106,
            "first_name": "Valli",
            "last_name": "Pataballa",
            "job_id": "IT_PROG",
            "salary": 4800
          },
          {
            "employee_id": 107,
            "first_name": "Diana",
            "last_name": "Lorentz",
            "job_id": "IT_PROG",
            "salary": 4200
          }
        ]
      }
    ]
  }
}
13.5.3.9 フィルタを使用した日付/タイムスタンプの操作
前の項で説明したフィルタのほとんどは、型がDateまたはTimestampのフィールドに適用できます。型がDateのフィールドにこれらのフィルタを適用するには、YYYY-MM-DDThh:mm:ssZという形式を使用する必要があります。日付フィールドでは、YYYY-MM-DDという形式も使用できます。型がTimestampのフィールドにこれらのフィルタを適用するには、YYYY-MM-DDThh:mm:ss.sssZという形式を使用する必要があります。次の問合せには、hire_dateフィールドを01 Jan 2006 から 01 Jun 2006までの範囲内に限定するフィルタが含まれています。
query{
  employees(where : {hire_date : {btwn : ["2006-01-01", "2006-06-01"]}}){
    employee_id
    first_name
    last_name
    job_id
    salary
    hire_date
  }
}
リクエスト:
curl --location 'http://localhost:8080/ords/hr/_/graphql' \--header 'Content-Type: application/json' \--data '{    "query": "query{ employees(where : {hire_date : {btwn : [\"2006-01-01\",
        \"2006-06-01\"]}}){employee_id first_name last_name job_id salary hire_date}
      }"}'
レスポンス:
{
  "data": {
    "employees": [
      {
        "employee_id": 103,
        "first_name": "Alexander",
        "last_name": "Hunold",
        "job_id": "IT_PROG",
        "salary": 9000,
        "hire_date": "2006-01-03T00:00:00Z"
      },
      {
        "employee_id": 106,
        "first_name": "Valli",
        "last_name": "Pataballa",
        "job_id": "IT_PROG",
        "salary": 4800,
        "hire_date": "2006-02-05T00:00:00Z"
      },
      {
        "employee_id": 112,
        "first_name": "Jose Manuel",
        "last_name": "Urman",
        "job_id": "FI_ACCOUNT",
        "salary": 7800,
        "hire_date": "2006-03-07T00:00:00Z"
      },
      {
        "employee_id": 139,
        "first_name": "John",
        "last_name": "Seo",
        "job_id": "ST_CLERK",
        "salary": 2700,
        "hire_date": "2006-02-12T00:00:00Z"
      },
      {
        "employee_id": 140,
        "first_name": "Joshua",
        "last_name": "Patel",
        "job_id": "ST_CLERK",
        "salary": 2500,
        "hire_date": "2006-04-06T00:00:00Z"
      },
      {
        "employee_id": 143,
        "first_name": "Randall",
        "last_name": "Matos",
        "job_id": "ST_CLERK",
        "salary": 2600,
        "hire_date": "2006-03-15T00:00:00Z"
      },
      {
        "employee_id": 153,
        "first_name": "Christopher",
        "last_name": "Olsen",
        "job_id": "SA_REP",
        "salary": 8000,
        "hire_date": "2006-03-30T00:00:00Z"
      },
      {
        "employee_id": 169,
        "first_name": "Harrison",
        "last_name": "Bloom",
        "job_id": "SA_REP",
        "salary": 10000,
        "hire_date": "2006-03-23T00:00:00Z"
      },
      {
        "employee_id": 170,
        "first_name": "Tayler",
        "last_name": "Fox",
        "job_id": "SA_REP",
        "salary": 9600,
        "hire_date": "2006-01-24T00:00:00Z"
      },
      {
        "employee_id": 176,
        "first_name": "Jonathon",
        "last_name": "Taylor",
        "job_id": "SA_REP",
        "salary": 8600,
        "hire_date": "2006-03-24T00:00:00Z"
      },
      {
        "employee_id": 177,
        "first_name": "Jack",
        "last_name": "Livingston",
        "job_id": "SA_REP",
        "salary": 8400,
        "hire_date": "2006-04-23T00:00:00Z"
      },
      {
        "employee_id": 180,
        "first_name": "Winston",
        "last_name": "Taylor",
        "job_id": "SH_CLERK",
        "salary": 3200,
        "hire_date": "2006-01-24T00:00:00Z"
      },
      {
        "employee_id": 181,
        "first_name": "Jean",
        "last_name": "Fleaur",
        "job_id": "SH_CLERK",
        "salary": 3100,
        "hire_date": "2006-02-23T00:00:00Z"
      },
      {
        "employee_id": 196,
        "first_name": "Alana",
        "last_name": "Walsh",
        "job_id": "SH_CLERK",
        "salary": 3100,
        "hire_date": "2006-04-24T00:00:00Z"
      },
      {
        "employee_id": 197,
        "first_name": "Kevin",
        "last_name": "Feeney",
        "job_id": "SH_CLERK",
        "salary": 3000,
        "hire_date": "2006-05-23T00:00:00Z"
      }
    ]
  }
}

13.6 データのソート

ソートでは、データを、1つ以上のフィールドを基準にして昇順または降順で並べ替えることができます。

ソート問合せ構文:
sortValue = "asc" | "desc" | "ASC" | "DESC"
sortExp = [{<fieldName1> : sortValue}, ... ,{<fieldNameN> : sortValue} ]
sort : <sortExp>
次の問合せでは、employee_idフィールドを降順に並べ替えるsortフィルタを指定します。
query {
  employees(sort : [ { employee_id : "desc" } ] ){
    employee_id
    first_name
    last_name
    salary
  }
}

リクエスト:

curl --location 'http://localhost:8080/ords/hr/_/graphql' \
--header 'Content-Type: application/json' \
--data '{
    "query": "query {  employees(sort : [ { employee_id : \"desc\" } ] )
	{    employee_id    first_name    last_name    salary  } }"
}'
レスポンス:
{
  "data": {
    "employees": [
      {
        "employee_id": 206,
        "first_name": "William",
        "last_name": "Gietz",
        "salary": 8300
      },
      {
        "employee_id": 205,
        "first_name": "Shelley",
        "last_name": "Higgins",
        "salary": 12008
      },
      {
        "employee_id": 204,
        "first_name": "Hermann",
        "last_name": "Baer",
        "salary": 10000
      },
      {
        "employee_id": 203,
        "first_name": "Susan",
        "last_name": "Mavris",
        "salary": 6500
      },
      {
        "employee_id": 202,
        "first_name": "Pat",
        "last_name": "Fay",
        "salary": 6000
      },
      {
        "employee_id": 201,
        "first_name": "Michael",
        "last_name": "Hartstein",
        "salary": 13000
      },
      {
        "employee_id": 200,
        "first_name": "Jennifer",
        "last_name": "Whalen",
        "salary": 4400
      },
     ...
    ]
  }
}

13.6.1 例: 複数の列を基準にしたソート

次の問合せには、department_idフィールドを降順にしsalaryフィールドを昇順にしてデータを並べ替えるsortフィルタが含まれています。
query {
  employees(sort : [ { department_id : "desc" } , { salary : "asc" }] ){
    employee_id
    first_name
    last_name
    salary
    department_id
  }
}

13.7 キーセット・ページ区切り

キーセット・ページ区切りを使用すると、指定した問合せから受け取ったデータを、limitoffsetを指定してページ区切りできます。ソート式を指定しなかった場合は、すべての行に一意に対応するためのソート引数として、デフォルトでROWIDが使用されます。

次の問合せでは、offsetパラメータとlimitパラメータを指定します。
query Employees {
  employees(limit: 3, offset: 5) {
    employee_id
    first_name
    last_name
    email
  }
}
リクエスト:
curl --location 'http://localhost:8080/ords/hr/_/graphql' \
--header 'Content-Type: application/json' \
--data '{
    "query": "query {  employees( limit: 3, offset: 5 ){  employee_id    first_name    last_name    email  } }"
}'

レスポンス:

{
    "data": {
        "employees": [
            {
                "employee_id": 105,
                "first_name": "David",
                "last_name": "Austin",
                "email": "DAUSTIN"
            },
            {
                "employee_id": 106,
                "first_name": "Valli",
                "last_name": "Pataballa",
                "email": "VPATABAL"
            },
            {
                "employee_id": 107,
                "first_name": "Diana",
                "last_name": "Lorentz",
                "email": "DLORENTZ"
            }
        ]
    }
}

13.7.1 例: 他のフィルタを使用したページ区切り

次の問合せでは、offsetパラメータとlimitパラメータを指定し、結果をemployee_id フィールドの降順で並べ替えます。
query {
  employees(sort : [ { employee_id : "DESC" } ], limit: 3, offset: 2){
    employee_id
    first_name
    last_name
    salary
    department_id
  }
}

13.7.2 例: ネストされたタイプでのページ区切り

次の問合せでは、employees、およびネストされたタイプemployees_manager_idの両方でlimitパラメータを指定し、ネストされたオブジェクトでの返される従業員の数を2つに制限します。
query{
  employees(limit : 1){
    employee_id
    first_name
    last_name
    job_id
    salary
    employees_manager_id(limit : 2){
      employee_id
      first_name
    }
  }
}

リクエスト:

curl --location 'http://localhost:8080/ords/hr/_/graphql' \
--header 'Content-Type: application/json' \
--data '{
    "query": "query {employees(limit : 1){employee_id first_name last_name job_id salary employees_manager_id(limit : 2){employee_id first_name}}}"
}'

レスポンス:

{
  "data": {
    "employees": [
      {
        "employee_id": 100,
        "first_name": "Steven",
        "last_name": "King",
        "job_id": "AD_PRES",
        "salary": 24000,
        "employees_manager_id": [
          {
            "employee_id": 101,
            "first_name": "Neena"
          },
          {
            "employee_id": 102,
            "first_name": "Lex"
          }
        ]
      }
    ]
  }
}

13.8 問合せでの動的引数の使用: 変数

GraphQL問合せで変数を静的値に置き換えるには、次の手順を実行します。
  1. 静的値を$variableNameに置き換えます。
  2. 問合せで受け入れられる変数の1つとして$variableNameを宣言してから、そのデータ型を指定します。
  3. 変数ディクショナリを個別に渡します

次の問合せでは、変数を使用して、フィルタにおいて動的値を使用するようにします。

query Employees($job_id : String, $min_salary : Int, $max_salary : Int){
    employees (where : { and : [
   {job_id : { eq : $job_id }},
   {salary : { btwn : [$min_salary, $max_salary] }} ]}){
        employee_id
        manager_id
        phone_number
        commission_pct
        department_id
        salary
        first_name
        email
        job_id
        hire_date
        last_name
    }
}

変数ディクショナリ:

{
    "job_id" : "IT_PROG",
    "min_salary" : 4000,
    "max_salary" : 6000
}
リクエスト:
curl --location 'http://localhost:8080/ords/hr/_/graphql' \
--header 'Content-Type: application/json' \
--data '{
    "query": "query Employees($job_id : String, $min_salary : Int, $max_salary : Int){ employees (where : { and : [\n   {job_id : { eq : $job_id }}, {salary : { btwn : [$min_salary, $max_salary] }} ]}){ employee_id  manager_id  phone_number commission_pct department_id salary first_name email job_id hire_date last_name }}",
    "operationName": "Employees",
    "variables": {
        "job_id": "IT_PROG",
        "min_salary": 4000,
        "max_salary": 6000
    }
}'

13.9 GraphiQL

Oracle REST Data Servicesには、GraphQLを探索するためのブラウザ内IDEであるGraphiQLが含まれています。次のエンドポイントを使用し、Rest対応ユーザー・データベース・スキーマの資格証明でログインします。
http://<HOST>:<PORT>/ords/<SCHEMANAME>/_/graphiql