Per invocare il servizio REST in modo sincrono è sufficiente scrivere:
List<User>> userList = userService.listUsers().execute().body();
Invocare il servizio REST in modo asincrono è altrettanto semplice.
userService.listUsers().enqueue(new Callback <List<User>> () {
@Override
public void onResponse(Call<List<User>> call, Response < List < User >> response) {
// in caso di successo
}
@Override
public void onFailure(Call<List<User>> call, Throwable t) {
// in caso di fallimento
}
});
Tutto questo è possibile grazie alla classe Call che consente di eseguire il metodo sia in modo sincrono che asincrono. Nel caso di gestione asincrona, la gestione del risultato dell'invocazione del servizio REST viene effettuata mediante callback.
Retrofit: i methodi HTTP
Il servizio REST nell'esempio presentato nel paragrafo precedente risponde al verbo HTTP GET
. Anche gli altri verbi HTTP possono essere utilizzati mediante annotazione. Per la definizione dei
metodi HTTP sono a disposizione le annotazioni: @GET
, @POST
, @PUT
, @DELETE
, @HEAD
,@GET
e @PATCH
.
Ogni annotazione consente di aggiungere un pezzo di path in più rispetto al base url definito quando si inizializzava Retrofit. Per specificare un parametro dellaquery string è invece disponibile l'annotazione @Query
@DELETE("users")
Call<Response<Void>> deleteUser(@Query("userId") long userId);
Per definire dinamicamente un pezzo dell'URI mediante un parametro del metodo è presente l'annotazione @Path
:
@GET("users/{userId}")
Call<List<User>> getUser(@Path("userId") long userId);
All'interno dell'annotazione @GET
, nella definizione del path relativo del servizio, è stato utilizzato un placeholder userId
coincidente con il valore specificato nell'annotazione @Path
.
Retrofit: passaggio di parametri
Retrofit consente di emulare l'invio di form con i relativi field:
@FormUrlEncoded
@POST("user/edit")
Call<User> updateUser(@Field("first_name") String first, @Field("last_name") String last);
Retrofit: manipolazione di header
Un'altra funzionalità di Retrofit è la possibilità di aggiungere o modificare anche gli header. Ci sono due modi per definire un header: o mediante apposita annotazione, o mediante un parametro annotato con l'annotazione @Header
:
@GET("user")
Call<User> getUser(@Header("Authorization") String authorization)
Retrofit: URL dinamici
Retrofit consente di definire l'url del servizio mediante apposito parametro decorato con l'annotazione @Url
:
@GET
Call<ResponseBody> list(@Url String url);
Retrofit: download di file
Una delle operazioni che molto probabilmente avete già incontrato è quella relativa al download di file. Con Retrofit questo può essere fatto in modo decisamente semplice:
@GET("/emails/allegati/example.zip")
Call<ResponseBody> downloadFileWithFixedUrl();
Il codice necessario a scaricare un file è:
AttachmentDownloadService downloadService = ServiceGenerator.create(AttachmentDownloadService.class);
Call<ResponseBody> call = downloadService.downloadFileWithDynamicUrlSync(fileUrl);
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
if (response.isSuccess()) {
Log.d(TAG, "server contacted and has file");
boolean writtenToDisk = writeResponseBodyToDisk(response.body());
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Log.e(TAG, "error");
}
});
Nel caso di file di una certa dimensione è meglio evitare di far passare il contenuto prima sulla RAM e poi sul disco. Questo si può ovviare con l'annotazione @Streaming
.
@Streaming
@GET
Call<ResponseBody> downloadFileWithDynamicUrlAsync(@Url String fileUrl);
Retrofit è una libreria open source scritta in Java e disponibile su github a questo link.
Il progetto proposto come esempio si appoggia ai servizi REST di JSONPlaceholder ed illustra l'integrazione tra Retrofit e Kripton.