|
| 1 | +# Microsoft Graph PHP SDK Upgrade Guide |
| 2 | + |
| 3 | +This guide highlights backward compatibility breaking changes introduced during major upgrades. |
| 4 | + |
| 5 | + |
| 6 | +## 1.x to 2.0 |
| 7 | + |
| 8 | +Version `2.0` highlights: |
| 9 | +- Support for National Clouds |
| 10 | +- Changes in creating a Graph client |
| 11 | +- Changes in configuring your HTTP client (including support for PSR-18 and HTTPlug's HttpAsyncClient implementations) |
| 12 | +- Introducing standardised Graph exception types `GraphClientException` and `GraphServiceException` as more specific `GraphException` types |
| 13 | +- Deprecates support for Guzzle `^6.0` |
| 14 | +- Strongly typed method parameters and return type declarations where possible |
| 15 | +- Psr compliance & other standardisation efforts in request classes and methods |
| 16 | + - Throwing `Psr\Http\Client\ClientExceptionInterface` instead of `\GuzzleHttp\Exception\GuzzleException` in request methods |
| 17 | + - Accepting and returning `Psr\Http\Message\StreamInterface` request bodies instead of `GuzzleHttp\Psr7\Stream` |
| 18 | + - Allow overwriting the default Guzzle client with `Psr\Http\Client\ClientExceptionInterface` for synchronous requests |
| 19 | + - Allow overwriting the default Guzzle client with HTTPlug's `Http\Client\HttpAsyncClient` for asynchronous requests |
| 20 | + |
| 21 | + |
| 22 | +### Support for National Clouds |
| 23 | +We have introduced `NationalCloud` containing Microsoft Graph API endpoint constants to enable you to easily |
| 24 | +set base URLs and in future authenticate against the various supported National Clouds |
| 25 | + |
| 26 | + |
| 27 | +### Creating a Graph client |
| 28 | +- Version 2 deprecates setting HTTP-specific config via methods e.g. `setProxyPort()` |
| 29 | +- Deprecates `setBaseUrl()` and `setApiVersion()` in favour of passing these into the constructor. |
| 30 | +The National Cloud set will be used as the base URL. |
| 31 | +- By default, the SDK will create a Guzzle HTTP client using our default config. |
| 32 | +The HTTP client can be customised as shown in the next section |
| 33 | + |
| 34 | + |
| 35 | +```php |
| 36 | +$graphClient = new Graph(); // uses https://graph.microsoft.com as base URL and a Guzzle client as defaults |
| 37 | +$response = $graphClient->setAccessToken("abc") |
| 38 | + ->setReturnType(Model\User::class) |
| 39 | + ->createRequest("GET", "/me") |
| 40 | + ->execute(); |
| 41 | +``` |
| 42 | + |
| 43 | + |
| 44 | +### Configuring HTTP clients for use with the Graph API |
| 45 | +We now support use of any HTTP client library that implements PSR-18 and HTTPlug's HttpAsyncClient interfaces. |
| 46 | +In addition, we provide a `HttpClientInterface` that you can implement with your HTTP client library of choice to support both sync and async calls. |
| 47 | + |
| 48 | +```php |
| 49 | +$graphClient = new Graph(NationalCloud::GLOBAL); // creates & uses a default Guzzle client under the hood |
| 50 | +``` |
| 51 | + |
| 52 | +#### 1. Custom configure a Guzzle client using the `HttpClientFactory` |
| 53 | +------------------------------------------------------------------------ |
| 54 | + To configure a Guzzle client to use with the SDK |
| 55 | + ```php |
| 56 | + $config = []; // your desired Guzzle client config |
| 57 | + $httpClient = HttpClientFactory::clientConfig($config)::createAdapter(); |
| 58 | + $graphClient = new Graph(NationalCloud::GLOBAL, $httpClient); |
| 59 | + ``` |
| 60 | + |
| 61 | + If you'd like to use the raw Guzzle client directly |
| 62 | + ```php |
| 63 | + $config = [ |
| 64 | + // custom request options |
| 65 | + ]; |
| 66 | + $guzzleClient = HttpClientFactory::clientConfig($config)::create(); |
| 67 | + $response = $guzzleClient->get("/users/me"); |
| 68 | + ``` |
| 69 | + |
| 70 | + We would have loved to allow you to pass your guzzle client directly to the HttpClientFactory, however we would not be able to attach our recommended configs since Guzzle's `getConfig()` method is set to be deprecated in Guzzle 8. |
| 71 | + |
| 72 | + |
| 73 | +#### 2. Configure any other HTTP client |
| 74 | +---------------------------------------- |
| 75 | +Implement the `Microsoft\Graph\Http\HttpClientInterface` and pass your implementation to the `Graph` constructor |
| 76 | + |
| 77 | +#### 3. Overwrite the HTTP client while making synchronous requests |
| 78 | +-------------------------------------------------------------------- |
| 79 | +The SDK supports use of any PSR-18 compliant client for synchronous requests |
| 80 | + |
| 81 | +```php |
| 82 | +$customPsr18Client = new Psr18Client(); |
| 83 | +$graphClient = new Graph(); |
| 84 | +$response = $graphClient->setAccessToken("abc) |
| 85 | + ->createRequest("GET", "/user/id") |
| 86 | + ->execute($customPsr18Client); // overwrites the default Guzzle client created by Graph() |
| 87 | +``` |
| 88 | + |
| 89 | +#### 4. Overwrite the HTTP client while making asynchronous requests |
| 90 | +---------------------------------------------------------------------- |
| 91 | +The SDK supports using any HTTPlug HttpAsyncClient implementation for asynchronous requests |
| 92 | +```php |
| 93 | +$customClient = new HttpAsyncClientImpl(); |
| 94 | +$graphClient = new Graph(); |
| 95 | +$response = $graphClient->setAccessToken("abc") |
| 96 | + ->createRequest("GET", "/user/id") |
| 97 | + ->executeAsync($customClient); // overwrite the default Guzzle client created by Graph() |
| 98 | +``` |
| 99 | + |
| 100 | + |
| 101 | +### Introducing the `GraphClientException` |
| 102 | +This will be the exception type thrown going forward with regard to Graph client and GraphRequest configuration issues |
| 103 | + |
| 104 | + |
| 105 | +### Introducing the `GraphServiceException` |
| 106 | +This is the new standard exception to be thrown for `4xx` and `5xx` responses from the Graph. The exception contains the error payload returned by the Graph API. |
| 107 | + |
| 108 | + |
| 109 | +### `GraphRequest` changes |
| 110 | + |
| 111 | +#### 1. Deprecated functionality |
| 112 | +--------------------------------- |
| 113 | +- Deprecates Guzzle-specific config and methods. We recommend using `HttpClientFactory` to configure your client: |
| 114 | + - Deprecated `setHttpErrors()`, `setTimeout()` |
| 115 | + - Deprecated `proxyPort` and `proxyVerifySSL` |
| 116 | +- `$headers` and `$requestBody` are no longer `protected` attributes. Now `private`. |
| 117 | +- Deprecates some getters: `getBaseUrl()`, `getApiVersion()`, `getReturnsStream()` |
| 118 | + |
| 119 | + |
| 120 | +#### 2. Setting return type |
| 121 | +---------------------------- |
| 122 | +- `setReturnType()` throws a `GraphClientException` if the return class passed is invalid. |
| 123 | +- Deprecates setting return type to `GuzzleHttp\Psr7\Stream` in favour of `Psr\Http\Message\StreamInterface` to get a stream returned. This is because of our efforts |
| 124 | +to make the SDK PSR compliant. |
| 125 | + |
| 126 | + |
| 127 | +#### 3. Headers |
| 128 | +---------------- |
| 129 | +- `getHeaders()` now returns `array<string, string[]` instead of previous `array<string, string>` |
| 130 | +- `addHeaders()` also supports passing `array<string, string|string[]>` |
| 131 | +- `addHeaders()` throws a `GraphClientException` if you attempt to overwrite the SDK Version header |
| 132 | +- Extra layer of security by preventing sending your authorization tokens to non-Graph endpoints. |
| 133 | + |
| 134 | +#### 4. Request Body |
| 135 | +---------------------- |
| 136 | +- Supports passing any PSR-7 `StreamInterface` implementation to `attachBody()` |
| 137 | + |
| 138 | + |
| 139 | +#### 5. Making Requests |
| 140 | +------------------------- |
| 141 | +- `execute()`, `download()` and `upload()` all accept any PSR-18 `ClientInterface` implementation to overwrite the SDK's default Guzzle client |
| 142 | +- `execute()` now throws PSR-18 `ClientExceptionInterface` as opposed to `\GuzzleHttp\Exception\GuzzleException` |
| 143 | +- `executeAsync()` now returns a HTTPlug `Http\Promise\Promise` instead of the previous Guzzle `GuzzleHttp\Promise\PromiseInterface` |
| 144 | +- `executeAsync()` fails with a PSR-18 `ClientExceptionInterface` for HTTP client issues or `GraphServiceException` for 4xx/5xx response |
| 145 | +- `download()` throws a `Psr\Http\Client\ClientExceptionInterface` as opposed to the previous `GuzzleHttp\Exception\GuzzleException` |
| 146 | +- `download()` and `upload()` now throw a `GraphClientException` if the SDK is unable to open the file path given and read/write to it. |
| 147 | + |
| 148 | + |
| 149 | +#### 6. Handling responses |
| 150 | +---------------------------- |
| 151 | +- For `4xx` and `5xx` responses, the SDK will throw a `GraphServiceException` which contains the error payload. |
| 152 | +- The status code is now an `int` from the previous `string` i.e. `getStatus()` |
| 153 | + |
| 154 | +### `GraphCollectionRequest` changes |
| 155 | +- Making `count()` requests now throws PSR-18 `ClientExceptionInterface` in case of any HTTP related issues & a `GraphClientException` if the `@odata.count` does not exist in the payload |
| 156 | +- `setPageSize()` throws a `GraphClientException` from the previous `GraphException` |
| 157 | +- `getPage()` throws `Psr\Http\Client\ClientExceptionInterface` from previous `GuzzleHttp\Exception\GuzzleException` |
| 158 | +- makes `setPageCallInfo()` and `processPageCallReturn()` `private` as these methods provide low level implementation detail |
| 159 | + |
0 commit comments