Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Microsoft Graph API Library for Go

1,790 views

Published on

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

Published in: Technology
  • Be the first to comment

  • Be the first to like this

Microsoft Graph API Library for Go

  1. 1. Microsoft Graph API Library for Go 2019-10-28 Takeshi Yaegashi Go Conference 2019 Autumn
  2. 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 した話」
  3. 3. 本日のお話 msgraph.go ● https://github.com/yaegashi/msgraph.go ● Microsoft Graph の紹介 ● msgraph.go の使用方法とアプリケーション、デモ (動画) ● Go 言語用クライアントライブラリの状況 ● msgraph.go の実装と工夫した点 ● 今後の計画
  4. 4. Microsoft Graph の紹介
  5. 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
  6. 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言語用ライブラリはまだない
  7. 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 という名前は既存のライブラリとの衝突を避けた結果
  8. 8. msgraph.go 使用法とアプリの例
  9. 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
  10. 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 が返される
  11. 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 定義が利用可能
  12. 12. msgraph.go 使用法:IDE による補完の活用 ● REST API 仕様が Go 言語化されており IDE による補完が活用できる ● ただし Visual Studio Code は知恵熱を出して沈黙することがあり たまに Restart Language Server する必要がある
  13. 13. msgraph.go アプリケーションの例:SharePoint ファイル共有アクセス ● SharePoint (OneDrive) ファイル共有のファイルを編集 ● Microsoft Flow で CI ジョブ開始 msgraph.go でファイルをダウンロード ● ファイル共有上の Excel ブックの中身を直接編集する API もある
  14. 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": "yaegashi@l0wdev.onmicrosoft.com" } }
  15. 15. msgraph.go の実装
  16. 16. クライアントライブラリの実装戦略 = コード生成 ● 膨大な MS Graph の機能をカバーするにはコード生成が必須 ● OData v4 の REST API の定義 (XML) から自動生成する ● https://graph.microsoft.com/v1.0/$metadata <EntityType Name="user" BaseType="microsoft.graph.directoryObject" OpenType="true"> <Property Name="userPrincipalName" Type="Edm.String" /> <Property Name="displayName" Type="Edm.String" /> <Property Name="passwordProfile" Type="microsoft.graph.passwordProfile" /> ... </EntityType> <ComplexType Name="passwordProfile"> <Property Name="password" Type="Edm.String" /> <Property Name="forceChangePasswordNextSignIn" Type="Edm.Boolean" /> <Property Name="forceChangePasswordNextSignInWithMfa" Type="Edm.Boolean" /> </ComplexType>
  17. 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 による実装
  18. 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# よくわからない
  19. 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
  20. 20. msgraph.go の生成ファイル 種類 生成ファイル名 v1.0 beta 定数 <EnumType> 〜Enum.go 188 528 モデル <EntityType> <ComplexType> 〜Model.go 638 1684 リクエスト 〜Request.go 247 645 アクション <Action> 〜Action.go 59 134 合計 1132 2991 ● 型名・メソッド名・ファイル名は C# (.NET) 版ライブラリに倣っている ● 生成ファイルの数が多すぎ?のため godoc.org で正しく表示できない
  21. 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埋め込み
  22. 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": "yaegashi@l0wdev.onmicrosoft.com", "mobilePhone": null, "officeLocation": null, "preferredLanguage": null, "surname": "八重樫", "userPrincipalName": "yaegashi@l0wdev.onmicrosoft.com", "id": "6764eb11-841c-444e-b770-0e0d8748ea0a" }
  23. 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
  24. 24. まとめ
  25. 25. msgraph.go 開発の進捗と今後の計画 ● これまでの進捗 ○ Go 言語で簡単な Microsft Graph アプリが作成できる段階 ● 今後の計画 ○ 未対応機能実装:<Function>、バッチリクエスト、長時間操作、etc. ○ 開発インフラ整備:ユニットテスト、CI/CD ○ ドキュメント:godoc.org 使えん問題解決、Graph API ドキュメント ○ ライブラリ API の安定化
  26. 26. 公式コードジェネレータとの関わりについて ● Microsoft Graph SDKs - Requirements and Design https://microsoftgraph.github.io/msgraph-sdk-design/ ● 公式 MSGraph SDK Code Generator を Go 言語に対応させたい ○ 今後のライブラリの保守を考えると、公式コードジェネレータに Go に対応して もらったほうが望ましいと思われる ○ msgraph.go のコード生成の経験 (jsonx とか) が生かせるはず
  27. 27. おわり msgraph.go ぜひ使ってみてください プルリクエストもお待ちしております!

×