6.2 KiB
id | title |
---|---|
5_to_6 | 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.
// 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
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:
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.
// 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!
// 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
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 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
:
// 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.