Microsoft Graph SDK for Java 6.x がGAしていた

# Microsoft Graph SDK for Java 6.x がGAしていた

Graph SDK for Java が 5.x から 6.x にアップデートされていたので、その備忘録です。

[microsoftgraph/msgraph-sdk-java: Java 用 Microsoft Graph SDK](https://github.com/microsoftgraph/msgraph-sdk-java)

生成されるコードが変わっており `kiota` を使うようになっています。そのため、全体的にコードが修正が必要です。所詮はAPIのラッパーSDKなので類推できる部分が多いのですが、アップデートする場合は使っているAPIの挙動を確認したほうがよいでしょう。

[microsoft/kiota: OpenAPI based HTTP Client code generator](https://github.com/microsoft/kiota)

## v6 での変更点

変更点は以下のドキュメントにまとめられています。

[msgraph-sdk-java/docs/upgrade-to-v6.md at dev · microsoftgraph/msgraph-sdk-java](https://github.com/microsoftgraph/msgraph-sdk-java/blob/dev/docs/upgrade-to-v6.md)

[microsoft/kiota-java: Kiota が生成した API クライアント用の Java ライブラリ。](https://github.com/microsoft/kiota-java)


変更点をいくつか上げていきましょう

### 非同期メソッドの廃

以前は、`getAsync()` がありましたが、`get()` のみ利用可能です。非同期の扱いは.NET程標準化されていないので致し方ない部分ではありますが、非同期処理を行う場合は自前で実装する必要があります。

`CompletableFuture` や、別の非同期フレームワークを使いましょうということらしいです。


### buildRequest() の廃止

以前のコードは、色々とパラメーターを設定したあと、`buildRequest()` を呼び出すことがお約束になっていましたが、無くなりました。


V5では以下の呼び出しが、

```java:v5
User me = graphClient.me().buildRequest().get();
```

V6では以下のようになります。

```java:v6
User me = graphClient.me().get();
```


### Getter/Setter アクセッサーの導入

V5では、フィールド変数が剥き出しになっていました。NETのプロパティ的に見せたかったのでしょうか。V6では、Getter/Setter アクセッサーが導入されました。

V5では以下の呼び出しが、

```java:v5
User me = graphClient.me().buildRequest().get();
String displayName = me.displayName;
```

V6では以下のようになります。

```java:v6
User me = graphClient.me().get();
String displayName = me.getDisplayName();
```

ただし、Setterは、`void` を返すので fluent に書かけません。API呼び出しはfluentに書けるのにちょっと残念。自動生成だろうから対応は簡単な気がしますが。

### Optionクラスの廃止

以前はリクエストオプションクラスを使っていましたが、廃止されました。代わりに、ラムダ式を使ってヘッダにリクセストを渡すようになりました。

```java:v6
User user = graphClient.users().byUserId("<User Id>").get(requestConfiguration -> {
            requestConfiguration.headers.add("headerKey", "headerValue");
        });
```

### 例外の変更

API呼び出しでの例外は、原則的に`GraphServiceException` が廃止され、代わりに、`ApiException` になります。`RuntimeException` を継承しているので、明示的にハンドリングするには、 きちんと `try-catch` を書きましょう。

他にも、バッチ操作ができるようなったり、バッキングストアと行った新機能が追加されているようです。


## コードサンプル

依存関係は以下です。ただ、アップグレードガイドのサンプル通りのコードを書くと依存関係エラーになる場合があって要注意です。Issue書きましたが、まだ解決されていません。

```xml
    <dependency>
      <groupId>com.microsoft.graph</groupId>
      <artifactId>microsoft-graph</artifactId>
      <version>6.7.0</version>
    </dependency>
    <dependency>
      <groupId>com.azure</groupId>
      <artifactId>azure-identity</artifactId>
      <version>1.12.0</version>
    </dependency>
```

`GraphServiceClient` は、`ClientSecretCredential` を使って生成します。`ClientSecretCredential` は、`azure.identity` ライブラリのクラスなので、ほぼJava SDK共通の仕組みです。

```java
        ClientSecretCredential creds = new ClientSecretCredentialBuilder()
            .clientId(clientId)
            .clientSecret(clientSecret)
            .tenantId(tenantId)
            .build();
        GraphServiceClient graphClient = new GraphServiceClient(creds, "https://graph.microsoft.com/.default");
```

IDでユーザーを取得する例です。ラムダ式でフィルターと、オプションを設定しています。現時点で、optionsに immutable list が設定されているバグがあって以下のコードは動きません。当面はリストを直接代入することで回避できます。Issue/PRしてあるので、いずれ直るでしょう。

```java
        var claimName = getExtensionName("mhv2linkid");
        var result = graphClient.users().byUserId(id).get(requestConfiguration -> {
            requestConfiguration.queryParameters.select = new String[] {
                claimName, "mail", "userPrincipalName", "displayName" };
                requestConfiguration.add(Arrays.asList(new RetryHandlerOption()));  // 現時点でエラーになる
            });
```

## 雑感

V5からの移植はそんな難しくないと思いますが、細かいところでハマるかもしれません。README通りにやってうまく動かなかったりして、依存関係沼にはまって時間を潰しました。個々のリクエストでリトライ設定することはできますが、全体でやる方法とかが分かってません。プロダクションで使う場合は、もうちょっと掘り下げて調べる必要がありあそうです。