虚無庵

徒然なるままに

microsoft_graph のコードを読む(2)

microsoft_graph のコードを読む - 虚無庵

続き。

前回 MicrosoftGraph クラスから OData::Service クラスを初期化しているところまで読みました。

OData::Service#initialize

github.com

コンストラクタは以下のようになっています。

def initialize(options = {}, &block)
  @api_version   = {
    'api-version': options[:api_version]
  } if options[:api_version]
  @auth_callback = options[:auth_callback] || block
  @base_url      = options[:base_url]
  @metadata_file = options[:metadata_file]
  @type_name_map = {}
  @metadata      = fetch_metadata
  populate_types_from_metadata
end

前提条件として OData::Service クラスには base_urlmetadata が attr_reader として定義されています。

初期化の内容をざっくり書くと以下のようなことをしています。

  • @api_versionmicrosoft_graph としての API バージョン(クライアントバージョン?)を設定しています
  • @auth_callbackUsage example を見てもらうと分かるのですが、Microsoft Graph に渡すトークンを Bearer として Proc で設定しています
  • @base_url : Microsoft Graph API エンドポイントの共通 URI を設定しています
  • @metadata_file :OData Protocol Schema が定義されている XML ファイルを設定します
  • @type_name_map :空ハッシュ値で初期化しています(今のところ用途不明)
  • @metadata@metada_file を nokogiri でパースして remove_namespaces! したものを設定しています
  • populate_types_from_metadata@type_name_map を初期化しています(具体的な意味は理解していない)

OData::Service#fetch_metadata

@metadata に代入される値は fetch_metadata メソッドの返り値です。

def fetch_metadata
  response = if @metadata_file
    File.read(@metadata_file)
  else # From a URL
    uri = URI("#{base_url}$metadata?detailed=true")
    Net::HTTP
      .new(uri.hostname, uri.port)
      .tap { |h| h.use_ssl = uri.scheme == "https" }
      .get(uri).body
  end
  ::Nokogiri::XML(response).remove_namespaces!
end

private メソッドとして定義されていて、@metadata_file に何か値が入っていればそれを使用し、そうでなければ Microsoft Graph に存在する OData Protocol Schema のメタデータファイルを取得して使用します。

あとは渡されたメタデータフ(XML)の namespace を削除した XML を返します。

OData::Service#populate_primitive_types

これが今のところ何のために必要なのか理解できていません。

def populate_primitive_types
  @type_name_map.merge!(
    "Edm.Binary"         => OData::BinaryType.new,
    "Edm.Date"           => OData::DateType.new,
    "Edm.Double"         => OData::DoubleType.new,
    "Edm.Guid"           => OData::GuidType.new,
    "Edm.Int16"          => OData::Int16Type.new,
    "Edm.Int32"          => OData::Int32Type.new,
    "Edm.Int64"          => OData::Int64Type.new,
    "Edm.Stream"         => OData::StreamType.new,
    "Edm.String"         => OData::StringType.new,
    "Edm.Boolean"        => OData::BooleanType.new,
    "Edm.DateTimeOffset" => OData::DateTimeOffsetType.new
  )
end

lib/odata/types/ 配下に定義されている型を司るクラス群をインスタンス化しているのは分かるのですが、これらが何のためにあるのか理解していません。

まとめ

ここから OData Protocol の仕様書をちゃんと読まないとダメなんだと思います。

もう心は折れています。

(続く?)