mirror of
https://github.com/Sarsoo/Spotify.NET.git
synced 2024-10-16 23:13:08 +01:00
Added migration from 5.x to 6.x to docs
This commit is contained in:
parent
35dbc7f57d
commit
66064aa0f5
154
SpotifyAPI.Docs/docs/5_to_6.md
Normal file
154
SpotifyAPI.Docs/docs/5_to_6.md
Normal file
@ -0,0 +1,154 @@
|
||||
---
|
||||
id: 5_to_6
|
||||
title: 5.x.x to 6.x.x
|
||||
---
|
||||
|
||||
## SpotifyAPI.Web
|
||||
|
||||
### Initialization
|
||||
|
||||
In `5.x`, a new `SpotifyWebAPI` instance could be created without supplying necessary values, since they were implemented as properties. With `6.x`, necessary values have to be given in the constructor and `SpotifyWebAPI` has been renamed to `SpotifyClient`. Also, `SpotifyClientConfig` has been introduced to give a better configuration experience, including retry handlers, automatic authenticators and proxy configurations.
|
||||
|
||||
```csharp
|
||||
// OLD
|
||||
var spotify = new SpotifyWebAPI { AccessToken = "YourAccessToken" };
|
||||
var spotify = new SpotifyWebAPI(ProxyConfig); // No access token - invalid
|
||||
|
||||
// NEW
|
||||
var spotify = new SpotifyClient("YourAccessToken");
|
||||
|
||||
var config = SpotifyClientConfig
|
||||
.CreateDefault()
|
||||
.WithToken("YourAccessToken");
|
||||
var spotify = new SpotifyClient(config);
|
||||
|
||||
var config = SpotifyClientConfig
|
||||
.CreateDefault()
|
||||
.WithAuthenticator(new ClientCredentialsAuthenticator(CLIENT_ID, CLIENT_SECRET)); // takes care of access tokens
|
||||
var spotify = new SpotifyClient(config);
|
||||
```
|
||||
|
||||
For some performance guides, have a look at the [Configuration Guide](./configuration.md)
|
||||
|
||||
### Proxy
|
||||
|
||||
In `5.x`, the proxy configuration could be passed to the `SpotifyWebAPI` constructor. In `6.x`, they're part of the HTTP Client. The built-in http client supports proxies out of the box:
|
||||
|
||||
```csharp
|
||||
var httpClient = new NetHttpClient(new ProxyConfig("localhost", 8080)
|
||||
{
|
||||
User = "",
|
||||
Password = "",
|
||||
SkipSSLCheck = false,
|
||||
});
|
||||
var config = SpotifyClientConfig
|
||||
.CreateDefault()
|
||||
.WithHTTPClient(httpClient);
|
||||
|
||||
var spotify = new SpotifyClient(config);
|
||||
```
|
||||
|
||||
### Calling API Endpoints
|
||||
|
||||
In `5.x`, there was one big instance to support all API endpoints. Parameters to these endpoints were passed directly as method parameters. Optional parameters were nullable and could be excluded. In `6.x`, every endpoint group (`albums`, `tracks`, `userprofile`) has their own API-Client, which is available as a property in a `SpotifyClient` instance. While URI path parameters are still passed as method parameter, query and body parameters are now passed as a grouped class instance, where required parameters are needed in the constructor and optional parameters can be supplied as properties. All endpoints are also only implemented as async methods.
|
||||
|
||||
```csharp
|
||||
// OLD:
|
||||
PrivateProfile profile = await spotify.GetPrivateProfileAsync();
|
||||
var playlists = await spotify.GetUserPlaylists(profile.Id, 100, 0);
|
||||
|
||||
// NEW:
|
||||
PrivateUser user = await spotify.UserProfile.Current();
|
||||
var playlists = await spotify.Playlists.GetUsers(user.Id, new PlaylistGetUsersRequest
|
||||
{
|
||||
Limit = 100,
|
||||
Offset = 0
|
||||
});
|
||||
```
|
||||
|
||||
All required arguments are checked for non-null values. If it's null, the methods will throw a `ArgumentNullException`
|
||||
|
||||
### Error/Header Handling
|
||||
|
||||
In `5.x`, all response models included a base error model, with properties like `Headers`, `Error` and `HasError`. This was not a good decision since response models should be clean and only contain API response data. In `6.x`, error handling is `Exception` based. For example, if the access token is invalid, calling API endpoints will throw a `APIUnauthorizedException`. If you hit the API too many times, the method will throw a `APITooManyRequestsException`. They all derive from a base exception `APIException`, which is also thrown in more general cases, e.g bad request input parameters. If you're interested in the headers of the last response, you can use `spotify.LastResponse`, **make sure there is only one thread using this instance!**
|
||||
|
||||
```csharp
|
||||
// OLD:
|
||||
PrivateProfile profile = await spotify.GetPrivateProfileAsync();
|
||||
if(profile.HasError())
|
||||
{
|
||||
// handle error
|
||||
}
|
||||
var headers = profile.Headers(); // access to headers
|
||||
|
||||
// NEW:
|
||||
try
|
||||
{
|
||||
PrivateProfile profile = await spotify.GetPrivateProfileAsync();
|
||||
var response = spotify.LastResponse; // response.Headers
|
||||
}
|
||||
catch (APIUnauthorizedException e)
|
||||
{
|
||||
// handle unauthorized error
|
||||
// e.Response contains HTTP response
|
||||
// e.Message contains Spotify error message
|
||||
}
|
||||
catch (APIException e)
|
||||
{
|
||||
// handle common error
|
||||
// e.Response contains HTTP response
|
||||
// e.Message contains Spotify error message
|
||||
}
|
||||
```
|
||||
|
||||
More Info: [Error Handling](./error_handling)
|
||||
|
||||
## SpotifyAPI.Web.Auth
|
||||
|
||||
In `5.x`, `SpotifyAPI.Web.Auth` contained every logic related to the OAuth flows. In `6.x`, `SpotifyAPI.Web.Auth` is only required if you need a HTTP Server for handling OAuth responses. For example, if you're in a ASP.NET environment or just use the [Client Credentials](client_credentials) flow, there is no need to install `SpotifyAPI.Web.Auth` anymore.
|
||||
|
||||
### Authorization Code Auth
|
||||
|
||||
As an example, this shows how to convert a `5.x` authorization code flow to `6.x`:
|
||||
|
||||
```csharp
|
||||
// OLD
|
||||
var auth =
|
||||
new AuthorizationCodeAuth(_clientId, _secretId, "http://localhost:4002", "http://localhost:4002",
|
||||
Scope.PlaylistReadPrivate | Scope.PlaylistReadCollaborative);
|
||||
auth.AuthReceived += AuthOnAuthReceived;
|
||||
auth.Start();
|
||||
auth.OpenBrowser();
|
||||
|
||||
private static async void AuthOnAuthReceived(object sender, AuthorizationCode payload)
|
||||
{
|
||||
var auth = (AuthorizationCodeAuth) sender;
|
||||
auth.Stop();
|
||||
|
||||
Token token = await auth.ExchangeCode(payload.Code);
|
||||
var spotify = new SpotifyWebAPI { AccessToken = token.AccessToken };
|
||||
await PrintUsefulData(spotify);
|
||||
}
|
||||
|
||||
// NEW
|
||||
var config = SpotifyClientConfig.CreateDefault();
|
||||
var server = new EmbedIOAuthServer(new Uri("http://localhost:5000/callback"), 5000);
|
||||
server.AuthorizationCodeReceived += async (sender, response) =>
|
||||
{
|
||||
await server.Stop();
|
||||
var tokenResponse = await new OAuthClient(config).RequestToken(new AuthorizationCodeTokenRequest(
|
||||
_clientId, _secretId, response.Code, server.BaseUri
|
||||
));
|
||||
|
||||
var spotify = new SpotifyClient(config.WithToken(tokenResponse.AccessToken));
|
||||
}
|
||||
await server.Start();
|
||||
|
||||
var loginRequest = new LoginRequest(server.BaseUri, _clientId, LoginRequest.ResponseType.Code)
|
||||
{
|
||||
Scope = new[] { Scopes.PlaylistReadPrivate, Scopes.PlaylistReadCollaborative }
|
||||
};
|
||||
BrowserUtil.Open(loginRequest.ToUri());
|
||||
```
|
||||
|
||||
While it is more code to write, there is a better seperation of concerns. For example, it is able to construct a `LoginRequest` without starting a server. This `LoginRequest` can also be used to forward the user to in a web-based context. The same auth server `EmbedIOAuthServer` can be used to receive `AuthorizationCodes` and `ImplictGrants` responses.
|
@ -14,8 +14,8 @@ module.exports = {
|
||||
'pagination',
|
||||
'retry_handling',
|
||||
'iplayableitem',
|
||||
'unit_testing'
|
||||
]
|
||||
'unit_testing',
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'category',
|
||||
@ -26,8 +26,8 @@ module.exports = {
|
||||
'implicit_grant',
|
||||
'authorization_code',
|
||||
'pkce',
|
||||
'token_swap'
|
||||
]
|
||||
'token_swap',
|
||||
],
|
||||
},
|
||||
'showcase',
|
||||
{
|
||||
@ -40,9 +40,14 @@ module.exports = {
|
||||
'example_cli_custom_html',
|
||||
'example_cli_persistent_config',
|
||||
'example_token_swap',
|
||||
'example_uwp'
|
||||
]
|
||||
'example_uwp',
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Migration Guides',
|
||||
items: ['5_to_6'],
|
||||
},
|
||||
],
|
||||
},
|
||||
]
|
||||
}
|
||||
};
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
Loading…
Reference in New Issue
Block a user