diff --git a/docs/upgrade-to-v6.md b/docs/upgrade-to-v6.md new file mode 100644 index 00000000000..a52987c6c95 --- /dev/null +++ b/docs/upgrade-to-v6.md @@ -0,0 +1,536 @@ +# Microsoft Graph Java SDK v6 Changelog and Upgrade Guide + +This document provides a list of changes and upgrade considerations for the Microsoft Graph Java SDK v6 release. + +## Overview + +Version 6.0.0 of the Microsoft Graph Java SDK is based on the new [Kiota](https://github.com/microsoft/kiota) code generation tool. By using Kiota the SDK is now able to support a broader range of Microsoft Graph API enpoints while also being more intuitive. Furthermore, [Graph-Core](https://github.com/microsoftgraph/msgraph-sdk-java-core) has also been updated to v3 which provides a great amount of added functionality; this makes v6 of the SDK a significant upgrade from v5. + +## Table Of Contents + +- [Breaking Changes](#breaking-changes) + - [Namespace Changes and Disambiguation](#namespace-changes-and-disambiguation) + - [Authentication](#authentication) + - [`BaseRequest` Changed to `RequestInformation`](#use-of-requestinformation-in-place-of-baserequestt) + - [Removal of `Async` Suffix](#removal-of-async-suffix-from-executor-methods) + - [Removal of `buildRequest`](#removal-of-buildrequest) + - [`CollectionPage` Changed to `CollectionResponse`](#collectionpage-types-changed-to-collectionresponse-types) + - [Private Properties](#properties-now-accessed-via-getters-and-setters) + - [Querying Collections](#querying-collections) + - [Indexing via Improved Fluent API Pattern](#change-in-indexing-via-improved-fluent-api-pattern) + - [Option Class Removal](#option-class-removal) + - [Header Options](#headers) + - [Query Parameter Options](#query-parameter-options) + - [Odata Function Parameters](#odata-function-parameters) + - [Odata Action Parameters](#odata-action-parameters) + - [Error Handling](#error-handling) + - [Drive Item Paths](#drive-item-paths) + - [Upload a Small File with conflictBehavior Set](#upload-a-small-file-with-conflictbehavior-set) +- [New Features](#new-features) + - [Backing Store](#backing-store) + - [Page Iterator](#pageiterator) + - [Batch Requests](#batch-requests) + - [Large File Upload Enhancements](#large-file-upload-enhancements) + - [Per-Request Options](#per-request-options) + - [Native Response Object](#native-response-object) + - [Support for OData Casts](#support-for-odata-casts) + + +## Breaking Changes + +The following is a list of breaking changes that users upgrading will want to consider while upgrading to v6 of the SDK. + +### Namespace Changes and Disambiguation + +Historically the SDK as well as the underlying Graph-Core library have all used the same parent namespace, `com.microsoft.graph.*`. This has caused issues for users who have wanted to use both the [v1.0](https://github.com/microsoftgraph/msgraph-sdk-java), [beta](https://github.com/microsoftgraph/msgraph-beta-sdk-java) and [core](https://github.com/microsoftgraph/msgraph-sdk-java-core) libraries in the same project. +This has the following implications: +- The v1.0 version of the SDK maintains the `com.microsoft.graph.*` namespace. +- The beta version of the SDK is now disambiguated to `com.microsoft.graph.beta.*`. +- The core library is now disambiguated to `com.microsoft.graph.core.*`. +- Models types are now stored in `com.microsoft.graph.models`/`com.microsoft.graph.beta.models` for v1.0 and beta respectively. +- RequestBuilder and RequestBody types reside in namespaces relative to the path they are calling. e.g. The `SendMailRequestBuilder` and `SendMailPostRequestBody` types will reside in the `com.microsoft.graph.users.item.sendmail`/`com.microsoft.graph.beta.users.item.sendMail` namespace if you are sending mail via `graphClient.me().sendMail().post(sendMailPostRequestBody)`. + +### Authentication + +The `GraphServiceClient` class now accepts an instance of `TokenCredential` from AzureIdentity directly rather than an instance of `TokenCredentialAuthProvider`. +Thus +```java +final DeviceCodeCredential credential = new DeviceCodeCredentialBuilder() + .clientId(appId) + .challengeConsumer(challenge -> System.out.println(challenge.getMessage())) + .build(); +final TokenCredentialAuthProvider tokenCredential = new TokenCredentialAuthProvider(scopes, credential); +GraphServiceClient graphClient = GraphServiceClient.builder() + .authenticationProvider(tokenCredential) + .buildClient(); +``` +becomes +```java +final DeviceCodeCredential credential = new DeviceCodeCredentialBuilder() + .clientId(appId) + .challengeConsumer(challenge -> System.out.println(challenge.getMessage())) + .build(); +GraphServiceClient graphClient = GraphServiceClient(credential, scopes); +``` +Custom authentication flows can be implemented by creating a class that implements [AccessTokenProvider](https://github.com/microsoft/kiota-java/blob/main/components/abstractions/src/main/java/com/microsoft/kiota/authentication/AccessTokenProvider.java) in conjunction with the [BaseBearerTokenAuthenticationProvider](https://github.com/microsoft/kiota-java/blob/main/components/abstractions/src/main/java/com/microsoft/kiota/authentication/BaseBearerTokenAuthenticationProvider.java) and passing that to GraphServiceClient constructor. +For example: +```java +public class CustomTokenProvider implements AccessTokenProvider { + @Override + public String getAuthorizationToken(URI uri, Map additionalAuthenticationContex) { + String token = ""; + // Handle token retrieval logic here + return token; + } + + @Override + public AllowedHostsValidator getAllowedHostsValidator() { + // Handle allowed hosts validation logic here + return new DefaultAllowedHostsValidator(); + } +``` +Then instantiate the GraphServiceClient as follows: +```java +BaseBearerTokenAuthenticationProvider authProvider = new BaseBearerTokenAuthenticationProvider(new CustomTokenProvider()); +GraphServiceClient graphClient = GraphServiceClient(authProvider); +``` +Alternatively a user may chose to create their own class that implements [AuthenticationProvider](https://github.com/microsoft/kiota-java/blob/main/components/abstractions/src/main/java/com/microsoft/kiota/authentication/AuthenticationProvider.java) and pass it to the GraphServiceClient constructor directly. +> Authentication using the graph client is no longer handled in the OkHttpClient middleware pipeline by default. Therefore, using the `GraphServiceClient(okHttpClient)` constructor will assume that the passed OkHttpClient has already been configured to handle authentication in its pipeline. +Otherwise, passing an instance of `AuthenticationProvider` to the constructor (`GraphServiceClient(authenticationProvider, okHttpClient)`) will make authenticated requests if the passed OkHttpClient is not already configured. + +### Use of `RequestInformation` in Place of `BaseRequest` + +The `RequestInformation` class is now used to represent requests in the SDK and the `BaseRequest` abstract class has been dropped. Using the fluent API patten a user can now get the `RequestInformation` instance for a request as follows: +```java +// Getting the RequestInformation for a Get request +RequestInformation requestInfo = graphClient.directoryObjects().toGetRequestInformation(); +// Getting the RequestInformation for a Post request +DirectoryObject directoryObject = new DirectoryObject(); +directoryObject.setId("1234"); +graphClient.directoryObjects().toPostRequestInformation(directoryObject); +``` + +### Removal of Async Suffix from Executor Methods + +The sdk no longer provides async methods for executing requests thus the async suffix has removed from executor methods. `postAsync()` is removed and now only `post()` is available, `getAsync()` is removed and only `get()`is available, etc. +> If users wish to execute requests asynchronusly they may choose to wrap their calls in CompleteableFutures or a separate async workflow. + +### Removal of `buildRequest()` + +In the previous version of the SDK the `buildRequest()` method call was neccessary when building and calling requests. +Previously a call to get the current user would look like the following: +```java +User me = graphClient.me().buildRequest().get(); +``` +The same call would be the following in v6: +```java +User me = graphClient.me().get(); +``` + +### CollectionPage Types Changed to CollectionResponse Types + +The `CollectionPage` suffix has been changed to `CollectionResponse` to better reflect the type of object that is returned from a request. +For example, a call to get a collection of users would return the following in v5: +```java +UserCollectionPage users = graphClient.users().buildRequest().get(); +``` +In v6 the same call would return: +```java +UserCollectionResponse users = graphClient.users().get(); +``` + +### Properties Now Accessed via Getters and Setters + +In v5 properties were accessed directly via the property name. In v6 properties are accessed via getters and setters. +For example, in v5 a user would access the `displayName` property of a `User` object as follows: +```java +User me = graphClient.me().buildRequest().get(); +String displayName = me.displayName; +``` +In v6 the same call would look like the following: +```java +User me = graphClient.me().get(); +String displayName = me.getDisplayName(); +``` + +### Querying Collections + +Querying collections has changed in v6 to more closely resemble the response from the API. +Previously a user would prepare to query a collection as follows: +```java +UserCollectionPage response = graphClient.users() + .buildRequest() + .get(); +List usersList = response.getCurrentPage(); +``` +In v6 the same call would look like the following: +```java +UserCollectionResponse response = graphClient.users().get(); +List usersList = response.getValue(); +``` + +### Change in Indexing via Improved Fluent API Pattern + +The fluent API pattern has changed slightly in v6. Previously the fluent API pattern would index into a collection through an overload method call in the request builder pattern. In v6 we have added the `byId` suffix to make it obvious when a user is indexing into a collection. +For example, retrieving a message by id would look like the following in v5: +```java +Message singleMessage = graphClient.me().messages("").buildRequest().get(); +``` +In v6 the same call would look like the following: +```java +Message singleMessage = graphClient.me().messages().byMessageId("").get(); +``` + +### Option Class Removal + +The `Option` class has been removed and is no longer used to define query parameters, headers, or function parameters. These classes have been replaced with more specific and intuitive implementations. + +#### Headers +Passing headers to requests has changed in v6. The `HeaderOption` class, which extends the `Option` class, has been removed and is no longer used to define headers. +Previously a user would pass headers to a request as follows: +```java +LinkedList