GraphQLのご紹介
はじめに
GraphQLはAPIクエリ言語(したがって「QL」リファレンス)のオープンな仕様であり、必要なデータを要求する機能を提供することで、統合をこれまで以上に迅速にすることができます。GraphQLは、必要なすべてのリソースを1回の呼び出しで取得するか、またはより少ない呼び出しで取得することによって、呼び出しの数と関連するラウンドトリップを減らすこともできます。
要するに、GraphQLは、応答ペイロードのサイズと発信されるコールの数に起因する帯域幅のオーバーヘッドを削減することで、統合に大きな影響を与えます。
APIフィルターは、REST API GET呼び出し時にリソース使用量を減らすために引き続き使用すべき重要な機能です。
OIDC/OAuth 2
CoupaのGraphQLクエリエンドポイントはOIDCを使用して認証され、承認はOAuth 2スコープを使用して処理されます。[設定] > [統合] > [Oauth 2/OpenID接続クライアント]に移動し、[作成]ボタンをクリックします(または/oauth 2/clients/newに移動します
)。クエリに適切なOAuth 2読み取りスコープを持つOIDCクライアントを作成します(書き込みはまだサポートされていません)。現在、クライアント資格情報の助成金タイプのみをサポートしています。
OIDCクライアントを作成したら、OIDCクライアント情報を使用してアクセストークンを取得します。アクセストークンの取得方法については説明しません。OIDCクライアント情報を使用してアクセストークンを取得する方法については、Coupa管理者またはCoupaサポートにお問い合わせください。
GraphQLクライアント
アクセストークンを取得したら、CoupaへのGraphQLリクエストに使用できる多くのツールがあります。これらのツールには、curl、Postman、およびGraphiQLが含まれます。
次の例では、GraphQLを使用します。GraphQLを使用する主な利点の1つは、スキーマを取得し、ユーザーフレンドリーな方法でスキーマを探索できることです。
Https://www.electronjs.org/apps/graphiqlからGraphiQLをダウンロードするか、HomebrewをインストールしたMacユーザーは次のコマンドを使用してください。
brew install -- cask graphiql
GraphiQLをインストールした後、それを起動すると、次のような画像が表示されます。
上の画像で注目すべき点:
- インスタンスURLを指定し、GraphQL Endpointアドレスバーに
/api/graphqlを追加します。
- HTTPヘッダーを編集して、アクセストークンを認証ヘッダーに追加します(下図を参照)。
- スキーマを表示するには、ドキュメントをクリックして展開します。
ヘッダーを編集するときは、[ヘッダーを追加]ボタンと以下の情報をクリックして、承認ヘッダーを追加します。
ヘッダー名:認証
ヘッダー値:ベアラー{YOUR ACCESS TOKEN}
必ずヘッダー値に「bearer」というプレフィックスを付けて
ください。そうしないと、認証できなくなります。
スキーマ
GraphiQLでドキュメントを展開すると、スキーマを探索することができます。スキーマを使用すると、クエリ可能なものとクエリの戻り値の種類を調べることができます。
突然変異はサポートされていないため、使用しないでください。
クエリ
GraphQLを使用すると、必要なデータに特化したクエリを実行できます。単一のオブジェクトまたはオブジェクトのコレクションのデータをクエリできます。
単独オブジェクト
単一のオブジェクトをクエリするには、小文字のオブジェクト名の単数形を使用し、オブジェクトIDを指定します。たとえば、user (id: 1)やexpenseReport (id: 1)などです。
データは、照会されたフィールドのデータとともにJSON形式で返されます。
コレクション
オブジェクトのコレクションをクエリするには、小キャメル大文字のオブジェクト名の複数形を使用します。例: users、expenseReports。
関連付け
GraphQLを使用すると、ネストされたデータをクエリすることができます。
上の画像は、単一の経費精算書のクエリを示しています(これはオブジェクトのコレクションでも機能します)。経費レポートでは、誰が作成したかと、レポートの経費明細に関する追加情報を照会しています。経費明細内でも、ネストされたデータをクエリしていることに注意してください。
カスタムフィールド
オブジェクトには、customFieldsというフィールド名でクエリできるカスタムフィールドがある場合があります。
カスタムフィールドは、いくつかのタイプ(テキスト、日付時間、ユーザーなど)のいずれかにすることができます。CustomFields フィールドは、その特定のカスタムフィールドのタイプを表示することができます。これにより、特にフラグメントを使用してこれらのタイプをクエリすることができます。
かけら
フラグメントを使用すると、フィールドのセットを構築してから、クエリに含めることができます。CustomFieldsの場合
、タイプレベルでフラグメントを指定できます。
上記の例では、ユーザー{…}の…とStringValue {…}の…の2つのフラグメントを指定しています。フラグメントは、Coupaにカスタムフィールドを指定されたタイプに変換しようとするよう指示します(該当する場合)。指定されたタイプに変換できる場合、要求されたフィールドが返されます。
高度なフィルタリングとクエリオプション
コレクションクエリには、応答をさらにフィルタリングするクエリと呼ばれる追加のオプションパラメータがあります。クエリオプションの形式は、REST APIで値をフィルタリングするためにも使用されるクエリ文字列パラメーターの形式です。
上記の例では、ID値を5未満にフィルタリングするクエリパラメータに"id [lt_or_eq ]= 5"を使用しています。これは、/api/invoices? id [lt_or_eq ]= 5の形でREST APIに直接ドロップすることもできます。
エラー
応答を確認するときは、常にJSON応答にエラーがないか確認する必要があります。エラーがある場合、エラーのメッセージと詳細が表示されます。
内省
スキーマ自体についてGraphQLにクエリすることもできます。これは、GraphQLがクライアントのスキーマを生成するために行うことです。以下は、典型的なイントロスペクションクエリの例です。
query IntrospectionQuery {
__ schema {
queryType {name}
mutationType {name}
サブスクリプションタイプ{name}
types {
... FullType
}
directives {
名前
説明
args {
... InputValue
} query IntrospectionQuery {
__ schema {
queryType {
名前
}
mutationType {
名前
}
subscriptionType {
名前
}
types {
... FullType
}
directives {
名前
説明
args {
... InputValue
}
onOperation
onFragment
onField
}
}
}
fragment FullType on __ Type {
kind
名前
説明
fields (includeDeprecated: true) {
名前
説明
args {
... InputValue
}
タイプ{
... TypeRef
}
isDeprecated
deprecationReason
}
inputFields {
... InputValue
}
interfaces {
... TypeRef
}
enumValues (includeDeprecated: true ){
名前
説明
isDeprecated
deprecationReason
}
possibleTypes {
... TypeRef
}
}
__ InputValue {上のfragment InputValue
名前
説明
タイプ{
... TypeRef
}
defaultValue
}
__ Type {上のfragment TypeRef
kind
名前
ofType {
kind
名前
ofType {
kind
名前
ofType {
kind
名前
}
}
}
}
onOperation
onFragment
onField
}
}
}
fragment FullType on __ Type {
kind
名前
説明
fields (includeDeprecated: true) {
名前
説明
args {
... InputValue
}
タイプ{
... TypeRef
}
isDeprecated
deprecationReason
}
inputFields {
... InputValue
}
interfaces {
... TypeRef
}
enumValues (includeDeprecated: true ){
名前
説明
isDeprecated
deprecationReason
}
possibleTypes {
... TypeRef
}
}
__ InputValue {上のfragment InputValue
名前
説明
type {... TypeRef}
defaultValue
}
__ Type {上のfragment TypeRef
kind
名前
ofType {
kind
名前
ofType {
kind
名前
ofType {
kind
名前
}
}
}
}
Postmanを使用したGraphQL
上記のすべてのGraphQLの例は、次の手順に従ってPostmanで実行することもできます。
- CoupaでOIDCトークンを生成します。詳細については、「OAuthを始める」を参照してください。
- アクセストークンが生成されたら、次のPOSTMAN構成を使用してGraphQL要求を開始します。
重要な注意事項
- すべてのリクエストはPOSTリクエストです
- すべての回答はJSONのみです
- 応答コード200が返された場合でも、常に応答本文にエラーがないか確認してください