2024年4月5日金曜日

Oracle REST Data Services Developer's Guideに載っているGraphQLのサンプルを実行する

こちらの記事「Oracle Database 23c Freeのコンテナ・イメージよりGraphQLを使える環境を作る」で作成した環境を使って、Oracle REST Data ServicesのDeveloper's Guideに記載されているGraphQLのクエリを実行してみます。GraphQLの実行にはInsomniaを使用します。

Oracle REST Data Services Developer's Guide, Release 23.4
10.4 Accessing Objects Using GraphQL queries

例題を実行する当たって、ORDSのPMのJeff Smithさんによる以下の記事も参照しています。

GraphQL Query Examples with Oracle & ORDS 23.3

Insomniaで新しくCollectionとしてSample Human Resourcesを作成した状態から、作業を始めます。

新しいリクエストを作成します。New HTTP Requestをクリックします。


リクエストの認証情報を設定します。Authメニューを開きOAuth 2.0を選択します。


ENABLEDにチェックを入れます。GRANT TYPEClient Credentialsを選択します。

ACCESS TOKEN URLは、RESTを有効化したスキーマhr/oauth/tokenを付加し、以下のURLになります。

http://localhost:8181/ords/hr/oauth/token

CLIENT IDおよびCLIENT SECRETは、SQL Developer Webの画面からコピペします。


以上を入力し、Fetch Tokensをクリックします。


ACCESS TOKENが取得できれば、GraphQLの問合せを発行する準備は完了です。


最初にスキーマ情報を確認します。

メソッドにGETを選択します。URLとして以下を設定します。

http://localhost:8181/ords/hr/_/graphql

BodyとしてNo Bodyを選択し、Sendを実行します。


JSONドキュメントとしてschemaNamedescriptionおよびSDLが返されます。


Bodyの形式としてGraphQL Queryを選択します。


イントロスペクションを有効にするため、schemaのメニューを開きRefresh Schemaを実行します。今回の環境ではスキーマが更新されることはないため、Automatic Fetchオフにします。

本記事を作成するに当たってInsomnia 8.6.1を使用していますが、ここでRefresh Schemaを実行すると、これ以降、発行するGraphQLのクエリのオペレーション名が必須になるようです。正確には、作成したリクエストで一度オペレーション名付きのクエリを発行した後は、anonymousのクエリは発行できない(リクエストに必ず属性operationNameが含まれる)模様です。


Oracle REST Data Servicesのマニュアルに記載されているGraphQLの例を実行してみます。例にオペレーション名が付けられていない場合は、オペレーション名を付加します。

10.4.2 Simple Query 
query Employees {
	employees {
		employee_id
		first_name
		last_name
		job_id
		salary
	}
}

10.4.3 Join Query

Example 1
query Locations {
	locations {
		city
		departments_location_id {
			department_name
			employees_department_id {
				first_name
				last_name
				salary
			}
		}
	}
}

Example 2
query Employees {
	employees {
		employee_id
		first_name
		last_name
		departments_department_id {
			department_id
			department_name
		}
	}
}

10.4.3.1 Circular Relationships Between Objects
query Employees {
	employees {
		employee_id
		first_name
		last_name
		manager_id
		manager_id_employees {
			first_name
			last_name
			employee_id
		}
	}
}

10.5.2 Filtering by Primary Key
query Employee {
	employees(primaryKey: { employee_id: 100 }) {
		employee_id
		first_name
		last_name
		job_id
		salary
	}
}

10.5.3.1 Example: EQUALS (eq) operator
query Employees {
	employees(where: { job_id: { eq: "IT_PROG" } }) {
		employee_id
		first_name
		last_name
		job_id
		salary
	}
}

10.5.3.2 Example: Greater than (>) Operator and Date Data Type
query Employees {
	employees(where: { hire_date: { gt: "2006-01-01T00:00:00Z" } }) {
		employee_id
		first_name
		last_name
		hire_date
	}
}

10.5.3.3 Example: LIKE (like) operator
query Employees {
	employees(where: { first_name: { like: "S%" } }) {
		employee_id
		first_name
		last_name
	}
}

10.5.3.4 Example: IN (in) operator
query Employees {
	employees(where: { job_id: { in: ["IT_PROG", "FI_ACCOUNT"] } }) {
		employee_id
		first_name
		last_name
		job_id
		salary
	}
}

10.5.3.5 Example: NOT (not) Operator
query Employees {
	employees(where: { not: { salary: { btwn: [2000, 10000] } } }) {
		employee_id
		first_name
		last_name
		job_id
		salary
	}
}

10.5.3.6 Example: AND (and) operator
query Employees {
	employees(
		where: {
			and: [{ job_id: { eq: "IT_PROG" } }, { salary: { btwn: [4000, 6000] } }]
		}
	) {
		employee_id
		first_name
		last_name
		job_id
		salary
	}
}

10.5.3.7 Example: OR (or) operator
query Employees {
	employees(
		where: {
			or: [{ job_id: { eq: "IT_PROG" } }, { job_id: { eq: "FI_ACCOUNT" } }]
		}
	) {
		employee_id
		first_name
		last_name
		job_id
		salary
	}
}

10.5.3.8 Example: Where Filter in Children Types
query Employees {
	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
		}
	}
}

10.5.3.9 Working with Dates/Timestamps Using Filters

サンプル・データv23.3にはマニュアルに記載されている範囲のhire_dateの従業員は存在しません。そのためhire_dateの範囲を変更しています。
query Employees {
	employees(where: { hire_date: { btwn: ["2016-01-01", "2016-06-01"] } }) {
		employee_id
		first_name
		last_name
		job_id
		salary
		hire_date
	}
}

10.6 Sorting the Data
query Employees {
	employees(sort: [{ employee_id: "desc" }]) {
		employee_id
		first_name
		last_name
		salary
	}
}

10.6.1 Example: Sorting by Multiple Columns
query Employees {
	employees(sort: [{ department_id: "desc" }, { salary: "asc" }]) {
		employee_id
		first_name
		last_name
		salary
		department_id
	}
}

10.7 Keyset Pagination
query Employees {
	employees(limit: 3, offset: 5) {
		employee_id
		first_name
		last_name
		email
	}
}

10.7.1 Example: Pagination with Other Filters
query Employees {
	employees(sort: [{ employee_id: "DESC" }], limit: 3, offset: 2) {
		employee_id
		first_name
		last_name
		salary
		department_id
	}
}

10.7.2 Example: Pagination in Nested Types
query Employees {
	employees(limit: 1) {
		employee_id
		first_name
		last_name
		job_id
		salary
		employees_manager_id(limit: 2) {
			employee_id
			first_name
		}
	}
}

10.8 Using Dynamic Arguments in Queries: Variables
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
	}
}
Variablesの指定
{
	"job_id": "IT_PROG",
	"min_salary": 4000,
	"max_salary": 6000
}

以上で一通り、マニュアルに記載されいているGraphQLのクエリを実行できました。