CData Software Blog

クラウド連携のCData Software の技術ブログです。

CData GraphQL Driver が自動スキーマ検出に対応しました

f:id:sugimomoto:20220208173955p:plain

こんにちは。CData Software Japan リードエンジニアの杉本です。

今回はCData GraphQL Driver の新機能を紹介します!

www.cdata.com

GraphQL はFacebookが開発したAPI向けのクエリ言語の1種です。API関係を触っている方やフロントエンドでガリゴリの方などは聞いたことがあるかなーと思います。

graphql.org

昨今は Shopify や Github が GraphQL ベースでAPIを公開したことも記憶に新しいですね。

shopify.dev

docs.github.com

そんなGraphQLに接続することができるCData GraphQL Driver ですが、以前まではリクエストしたいGraphQLのクエリに応じて、都度スキーマファイルを作成する必要がありました。

cdn.cdata.com

しかし、今回のアップデートにより、このスキーマファイルの自動検出・動的生成に対応したので紹介します!

対象の GraphQL

今回はわかりやすく、シンプルなGraphQLをベースにして解説するため、以下のHasra というサービスでGraphQLエンドポイントを生成して接続してみました。

hasura.io

サンプルとして2つのテーブル「Accounts・Contacts」を用意しています。

f:id:sugimomoto:20220208172029p:plain

f:id:sugimomoto:20220208172034p:plain

「Accounts 1:N Contacts」のリレーションがはられていて、以下のようにクエリすることができるようになっています。

query MyQuery {
  Accounts {
    AccountName
    AccountNumber
    Contacts {
      FirstName
      LastName
    }
  }
}

f:id:sugimomoto:20220208172040p:plain

使い方

それでは、上記GraphQLに接続してみましょう。実は今回の新機能、最初から有効化されているので、特に設定などは必要ありません。そのまま接続すると利用できます。

接続前に、まず一点注意なのですが、GraphQLはサービスそれぞれで認証アプローチが異なります。Hasraの場合は拡張HeaderでAPI Keyを指定する形式です。

なので、以下の画面でGraphQLのエンドポイントURLと「x-hasura-admin-secret」の値を保存しておきましょう。

f:id:sugimomoto:20220208172047p:plain

続いて、CData GraphQL Driverを準備します。

テクノロジーはなんでもOKなので、今回はODBC Driverを利用しました。

www.cdata.com

f:id:sugimomoto:20220208172055p:plain

ODBCドライバーをインストール後、接続プロパティの画面で以下のような設定を行います。

プロパティ名 備考
AuthScheme NONE カスタムヘッダーで認証を行うため、NONEに指定します。
URL 例)https://massive-walrus-84.hasura.app/v1/graphql GraphQLエンドポイントURLを指定します。
CustomHeaders 例)x-hasura-admin-secret:YOUR_API_KEY Hasraから取得したAPI KeyをHedaer名と一緒に設定します。

f:id:sugimomoto:20220208172103p:plain

これで「接続テスト」をクリックし、以下のようなメッセージが表示されればOKです。

f:id:sugimomoto:20220208172111p:plain

せっかくなので、Microsoft のBIツール「Power BI」から接続してみましょう。

「データを取得」の画面でODBCを選択し

f:id:sugimomoto:20220208172118p:plain

先程構成した「CData GraphQL Source」を選択します。

f:id:sugimomoto:20220208172122p:plain

認証は先程設定しているので、Windowsの現在の資格情報で接続してOKです。

f:id:sugimomoto:20220208172127p:plain

これで、ナビゲーターの画面に移動すれば、今回追加された機能によって、テーブルが自動検出され、データが取得できます。

f:id:sugimomoto:20220208172134p:plain

何も設定が必要なく利用できる新機能ですが、とても便利です。

データモデリング解説

ちなみに、今回は2つのテーブルを対象としていましたが、GraphQLのクエリ構造を読み取って、3テーブルに変換しています。

これはGraphQLの大きな特徴である「ネストされたクエリ」のデータもCData Driver のインターフェースでアクセスしやすいように配慮・デザインされているためです。

f:id:sugimomoto:20220208172204p:plain

例えば、上記のAccountsテーブルでは内部的に以下のようなクエリが発行されています。

{
  Accounts {
    AccountName
    AccountNumber
    Id
  }
}

f:id:sugimomoto:20220208172343p:plain

そして、「Accounts_Contacts」テーブルでは、Accountsテーブルを主体として、1:NリレーションのContactsもJOINされた形の結果が取得できます。

f:id:sugimomoto:20220208172356p:plain

これは内部的には以下のようなクエリが発行されています。GraphQL長所とも言える、1:Nのネストされたデータを取得できる書き方ですね。

{
  Accounts {
    Contacts {
      AccountId
      FirstName
      Id
      LastName
      TEL
    }
    Id
  }
}

f:id:sugimomoto:20220208172424p:plain

Contactsは以下のようにデータを取得できます。

f:id:sugimomoto:20220208172429p:plain

ここでのポイントはContactsテーブルに対してN:1の関係になっているAccountsテーブルの関連結果も取得していることです。Accountに含まれるカラムの結果も取得しているのがポイントですね。

{
  Contacts {
    Account {
      AccountName
      AccountNumber
      Id
    }
    AccountId
    FirstName
    Id
    LastName
    TEL
  }
}

f:id:sugimomoto:20220208172434p:plain

このようにGraphQLのデータをCData Driverで扱うためにうまくモデリングして提供するようになっています。

スキーマ検出の仕組み

最後にこのスキーマ検出の仕組みについてざっと解説しておきます。

GraphQL内部には introspection という、GraphQLでサポートされているQueryやMutationをクエリすることができる機能が存在します。

https://graphql.org/learn/introspection/

GraphiQLなどの画面でオートコンプリートを効かせられるのは、このスキーマ情報を読み取っているためです。

この機能を使って、CData Driverでは対象のGraphQL APIにどのようなQueryやMutation、データ構造が存在しているのか?を検知して、モデリングするようになっています。

ちなみに、内部的には以下のようなクエリを発行して、スキーマ情報を取得しています。

{
  __schema {
    queryType {
      name
    }
    mutationType {
      name
    }
    subscriptionType {
      name
    }
    types {
      ...FullType
    }
    directives {
      name
      description
      locations
      args {
        ...InputValue
      }
    }
  }
}

fragment FullType on __Type {
  kind
  name
  description
  fields(includeDeprecated: false) {
    name
    description
    args {
      ...InputValue
    }
    type {
      ...TypeRef
    }
    isDeprecated
    deprecationReason
  }
  inputFields {
    ...InputValue
  }
  interfaces {
    ...TypeRef
  }
  enumValues(includeDeprecated: false) {
    name
    description
    isDeprecated
    deprecationReason
  }
  possibleTypes {
    ...TypeRef
  }
}

fragment InputValue on __InputValue {
  name
  description
  type {
    ...TypeRef
  }
  defaultValue
}

fragment TypeRef on __Type {
  kind
  name
  ofType {
    kind
    name
    ofType {
      kind
      name
      ofType {
        kind
        name
        ofType {
          kind
          name
          ofType {
            kind
            name
            ofType {
              kind
              name
              ofType {
                kind
                name
              }
            }
          }
        }
      }
    }
  }
}

GraphiQL画面上で実行してみると、以下のようにオブジェクトやクエリ、プロパティの情報が取得できているのがわかりますね。

f:id:sugimomoto:20220208172444p:plain

この情報を元に、CData Driver ではテーブル化の判断を行って処理しています。

おわりに

このようにデータモデリングを行っていることにより、様々なGraphQL APIへスムーズに対応できるようになっています。

その他まだまだ色々と機能があるので、随時このBlogで解説していきたいと思います。

利用していて、わからない点、気になる点があれば、テクニカルサポートまでお気軽にお問い合わせください。

https://www.cdata.com/jp/support/submit.aspx