Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Microsoft Graph API Library for Go

Microsoft Graph API Library for Go

Go Conference Tokyo 2019 Autumn
https://gocon.jp/sessions/microsoft_graph_api_library_for_go/

msgraph.go demo - SharePoint Online + Microsoft Flow + GitLab CI
https://www.youtube.com/watch?v=DwKk405XyF4

msgraph.go
https://github.com/yaegashi/msgraph.go

YAEGASHI Takeshi

October 28, 2019
Tweet

More Decks by YAEGASHI Takeshi

Other Decks in Technology

Transcript

  1. Microsoft Graph API Library for Go
    2019-10-28 Takeshi Yaegashi
    Go Conference 2019 Autumn

    View full-size slide

  2. 自己紹介
    八重樫 剛史 Takeshi Yaegashi
    ● 株式会社バンダイナムコスタジオ所属
    ● Linux・Unix・OSS・低レベルなことが好きなエンジニア
    ● ホームページ・ブログ https://l0w.dev
    ● Go のお仕事
    ○ Raspberry Pi を使った IoT 案件
    ○ スマホゲームアプリのサーバ
    ● Go のお話
    ○ golang.tokyo #25「golang binary hacks」
    ○ golang.tokyo #26「Raspberry Pi + Go で IoT した話」

    View full-size slide

  3. 本日のお話
    msgraph.go
    ● https://github.com/yaegashi/msgraph.go
    ● Microsoft Graph の紹介
    ● msgraph.go の使用方法とアプリケーション、デモ (動画)
    ● Go 言語用クライアントライブラリの状況
    ● msgraph.go の実装と工夫した点
    ● 今後の計画

    View full-size slide

  4. Microsoft Graph の紹介

    View full-size slide

  5. Microsoft Graph API とは
    ● Microsoft のクラウドサービス (Office 365 など) を扱う統合 API
    https://docs.microsoft.com/ja-jp/graph/overview
    ● 次のようなリソースを操作するアプリを作成できる
    ○ ユーザー・グループ・デバイス・ライセンス (Azure Active Directory)
    ○ メール・連絡先・予定表・チャット (Outlook, Teams)
    ○ ストレージ・ファイル・サイト (OneDrive, SharePoint)
    ● Office 365 を導入している会社や個人にとって利用価値が高い API

    View full-size slide

  6. Microsoft Graph API プログラミング
    ● 共通のエンドポイントを使用する REST API セット
    ○ API Endpoint (v1.0): https://graph.microsoft.com/v1.0
    ○ API Reference: https://docs.microsoft.com/ja-jp/graph/api/overview
    ● 各言語・処理系用のクライアントライブラリ (SDK)
    https://microsoftgraph.github.io/msgraph-sdk-design/
    ○ .NET(C#), Java, JavaScript, Objective C, PHP, Ruby, Python, …
    ○ 2019年10月現在、公式のGo言語用ライブラリはまだない

    View full-size slide

  7. Go 言語用のクライアントライブラリの状況
    ● GitHub をリポジトリ検索してみると…
    ○ https://github.com/search?l=Go&q=msgraph&type=Repositories
    ○ go-msgraph, msgraph-go, msgoraph, … 未完のプロジェクトが多数
    ● msgraph.go = 今回紹介するライブラリ
    ○ https://github.com/yaegashi/msgraph.go
    ○ 2019年7月に開発開始
    ○ msgraph.go という名前は既存のライブラリとの衝突を避けた結果

    View full-size slide

  8. msgraph.go 使用法とアプリの例

    View full-size slide

  9. msgraph.go 使用法:Graph Client の作成
    import "github.com/yaegashi/msgraph.go/auth"
    import msgraph "github.com/yaegashi/msgraph.go/v1.0"
    // Create HTTP client with Azure AD OAuth2 device authorization grant
    m := auth.NewTokenManager()
    t, err := m.DeviceAuthorizationGrant(tenantID, clientID, scope, nil)
    if err != nil { /*...*/ }
    httpClient := t.Client(context.Background())
    // Create MS Graph client
    graphClient := msgraph.NewClient(httpClient)
    ● 最初に Graph Client を作成する
    ● Azure Active Directory に対して OAuth2 認証を行う http.Client が必要
    https://github.com/yaegashi/msgraph.go/tree/master/auth

    View full-size slide

  10. msgraph.go 使用法:REST API 発行
    // Get current user’s information
    // "GET https://graph.microsoft.com/v1.0/me" -> *msgraph.User
    user, err := graphClient.Me().Request().Get()
    if err != nil { /*...*/ }
    // Get current user's OneDrive root folder items
    // "GET https://graph.microsoft.com/v1.0/me/drive/root/children" -> []msgraph.DriveItem
    items, err := graphClient.Me().Drive().Root().Children().Request().Get()
    if err != nil { /*...*/ }
    // Create new group
    // "POST https://graph.microsoft.com/v1.0/groups" -> *msgraph.Group
    newGroup := &msgraph.Group{ /*...*/ }
    createdGroup, err := graphClient.Groups().Request().Add(newGroup)
    if err != nil { /*...*/ }
    ● メソッド呼び出しの連結で REST API の HTTP リクエストが出せる
    レスポンスの JSON に対応するモデルの struct が返される

    View full-size slide

  11. msgraph.go 使用法:REST API 対応コード
    REST API msgraph.go 説明
    GET /users users, err := cli.Users().Request().Get() 全ユーザー取得
    POST /users
    u := &msgraph.User{/*...*/}
    user, err := cli.Users().Request().Add(u)
    ユーザー作成
    GET /users/XXX user, err := cli.Users().ID("XXX").Request().Get() ユーザー取得
    PATCH /users/XXX
    u := &msgraph.User{/*...*/}
    err := cli.Users().ID("XXX").Request().Update(u)
    ユーザー更新
    DELETE /users/XXX err := cli.Users().ID("XXX").Request().Delete() ユーザー削除
    ● 各リソースコレクションの操作メソッドとモデル struct 定義が利用可能

    View full-size slide

  12. msgraph.go 使用法:IDE による補完の活用
    ● REST API 仕様が Go 言語化されており IDE による補完が活用できる
    ● ただし Visual Studio Code は知恵熱を出して沈黙することがあり
    たまに Restart Language Server する必要がある

    View full-size slide

  13. msgraph.go アプリケーションの例:SharePoint ファイル共有アクセス
    ● SharePoint (OneDrive) ファイル共有のファイルを編集
    ● Microsoft Flow で CI ジョブ開始 msgraph.go でファイルをダウンロード
    ● ファイル共有上の Excel ブックの中身を直接編集する API もある

    View full-size slide

  14. msgraph.go アプリケーションの例:msgraph-sshpubkey
    ● https://github.com/yaegashi/msgraph.go/tree/master/cmd/msgraph-sshpubkey
    ● SSH 公開鍵を User の extensions で管理できる (オープン拡張機能)
    ● sshd_config の AuthorizedKeysCommand で実行してユーザー認証
    ● サイズ 5.6MB の実行ファイルで導入が容易
    AuthorizedKeysCommand /usr/bin/msgraph-sshpubkey -config /etc/msgraph-sshpubkey.json -login %u
    AuthorizedKeysCommandUser root
    $ cat /etc/msgraph-sshpubkey.json
    {
    "tenant_id": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
    "client_id": "YYYYYYYY-YYYY-YYYY-YYYY-YYYYYYYYYYYY",
    "client_secret": "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ",
    "login_map": {
    "yaegashi": "[email protected]"
    }
    }

    View full-size slide

  15. msgraph.go の実装

    View full-size slide

  16. クライアントライブラリの実装戦略 = コード生成
    ● 膨大な MS Graph の機能をカバーするにはコード生成が必須
    ● OData v4 の REST API の定義 (XML) から自動生成する
    ● https://graph.microsoft.com/v1.0/$metadata




    ...






    View full-size slide

  17. 2 種類のコードジェネレータの存在
    ● MSGraph SDK Code Generator
    https://github.com/microsoftgraph/MSGraph-SDK-Code-Generator
    ○ Microsoft 公式 MS Graph SDK コードジェネレータ
    ○ C# および .NET Framework による実装 (開発に Windows が必要)
    ○ C# (.NET Core), Java, JavaScript, Objective-C, Python
    ● msgraph.go コードジェネレータ
    https://github.com/yaegashi/msgraph.go/gen
    ○ Pure Go による実装

    View full-size slide

  18. なぜ MSGraph SDK Code Generator があるのに msgraph.go を?
    ● 実は MSGraph SDK Code Generator の存在を知らなかった
    ○ C# (.NET) 用のライブラリを参考に msgraph.go を作り始めて
    しばらく経ってから気づいた
    ○ 現在の msgraph.go は MSGraph SDK Code Generator を
    パクったリスペクトしたコード生成を行う
    ● MSGraph SDK Code Generator はクロスプラットフォームでない
    ○ 新しい言語の対応を追加するには Windows の開発環境が必要
    ○ C# よくわからない

    View full-size slide

  19. msgraph.go のコード生成
    ● go generate ./gen
    ○ metadata XML のダウンロードとコード生成を行う
    ○ v1.0 と beta の 2 つの API バージョンのコードを生成する
    ○ text/template によりテンプレートファイルからコードを生成する
    ○ 生成したファイルに goimports を実行して整形・import 解決
    package gen
    //go:generate go run msgraph-download.go -pretty -baseURL https://graph.microsoft.com/v1.0 -out metadata-v1.0.xml
    //go:generate go run msgraph-download.go -pretty -baseURL https://graph.microsoft.com/beta -out metadata-beta.xml
    //go:generate go run msgraph-generate.go -baseURL https://graph.microsoft.com/v1.0 -in metadata-v1.0.xml -out ../v1.0
    //go:generate go run msgraph-generate.go -baseURL https://graph.microsoft.com/beta -in metadata-beta.xml -out ../beta

    View full-size slide

  20. msgraph.go の生成ファイル
    種類 生成ファイル名 v1.0 beta
    定数 〜Enum.go 188 528
    モデル 〜Model.go 638 1684
    リクエスト 〜Request.go 247 645
    アクション 〜Action.go 59 134
    合計 1132 2991
    ● 型名・メソッド名・ファイル名は C# (.NET) 版ライブラリに倣っている
    ● 生成ファイルの数が多すぎ?のため godoc.org で正しく表示できない

    View full-size slide

  21. 生成コードの例:モデル struct の定義
    type User struct {
    DirectoryObject
    UserPrincipalName *string `json:"userPrincipalName,omitempty"`
    DisplayName *string `json:"displayName,omitempty"`
    PasswordProfile *PasswordProfile `json:"passwordProfile,omitempty"`
    /*...*/
    }
    type PasswordProfile struct {
    Object
    Password *string `json:"password,omitempty"`
    ForceChangePasswordNextSignIn *bool `json:"forceChangePasswordNextSignIn,omitempty"`
    ForceChangePasswordNextSignInWithMFA *bool `json:"forceChangePasswordNextSignInWithMfa,omitempty"`
    }
    ● encoding/json の利用を前提としたフィールド名とタグがつけられる
    ● 基本型 (int, string, bool, etc.) や構造体はすべてポインタ型となる
    ● struct 埋め込みによりモデル継承、全モデルは Object struct をひとつ含む
    struct埋め込み

    View full-size slide

  22. JSON に含まれる追加データ
    ● API が返す JSON には、モデル struct のフィールドで定義されていない
    "@odata.context" のような追加データが含まれることがよくある
    ● これらを単に encoding/json で Unmarshal すると失われてしまう
    GET https://graph.microsoft.com/v1.0/me/
    {
    "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#users/$entity",
    "businessPhones": [],
    "displayName": "八重樫 剛史",
    "givenName": "剛史",
    "jobTitle": null,
    "mail": "[email protected]",
    "mobilePhone": null,
    "officeLocation": null,
    "preferredLanguage": null,
    "surname": "八重樫",
    "userPrincipalName": "[email protected]",
    "id": "6764eb11-841c-444e-b770-0e0d8748ea0a"
    }

    View full-size slide

  23. Object / AdditionalData / jsonx による追加データの対応
    type Object struct {
    AdditionalData map[string]interface{} `json:"-" jsonx:"true"`
    }
    func (o *Object) SetAdditionalData(key string, val interface{}) {/*...*/}
    func (o *Object) GetAdditionalData(key string) (interface{}, bool) {/*...*/}
    user, err := graphClient.Me().Request().Get()
    if err != nil { /*...*/ }
    if context, ok := user.GetAdditionalData("@odata.context"); ok {
    fmt.Println(context)
    // -> https://graph.microsoft.com/v1.0/$metadata#users/$entity
    }
    ● Object の AdditionalData がいわゆる catch-all 動作で追加データを格納する
    ● encoding/json を改造・拡張した jsonx により実現
    https://github.com/yaegashi/msgraph.go/tree/master/jsonx

    View full-size slide

  24. msgraph.go 開発の進捗と今後の計画
    ● これまでの進捗
    ○ Go 言語で簡単な Microsft Graph アプリが作成できる段階
    ● 今後の計画
    ○ 未対応機能実装:、バッチリクエスト、長時間操作、etc.
    ○ 開発インフラ整備:ユニットテスト、CI/CD
    ○ ドキュメント:godoc.org 使えん問題解決、Graph API ドキュメント
    ○ ライブラリ API の安定化

    View full-size slide

  25. 公式コードジェネレータとの関わりについて
    ● Microsoft Graph SDKs - Requirements and Design
    https://microsoftgraph.github.io/msgraph-sdk-design/
    ● 公式 MSGraph SDK Code Generator を Go 言語に対応させたい
    ○ 今後のライブラリの保守を考えると、公式コードジェネレータに Go に対応して
    もらったほうが望ましいと思われる
    ○ msgraph.go のコード生成の経験 (jsonx とか) が生かせるはず

    View full-size slide

  26. おわり
    msgraph.go ぜひ使ってみてください
    プルリクエストもお待ちしております!

    View full-size slide