Introduksjon til ettermontering

1. Oversikt

Retrofit er en typesikker HTTP-klient for Android og Java - utviklet av Square (Dagger, Okhttp).

I denne artikkelen skal vi forklare hvordan du bruker ettermontering, med fokus på de mest interessante funksjonene. Mer spesielt vil vi diskutere synkron og asynkron API, hvordan du bruker den med autentisering, logging og noen gode modelleringsrutiner.

2. Sette opp eksemplet

Vi begynner med å legge til ettermonteringsbiblioteket og Gson-omformeren:

 com.squareup.retrofit2 ettermontering 2.3.0 com.squareup.retrofit2 omformer-gson 2.3.0 

For de nyeste versjonene, ta en titt på Retrofit og converter-gson på Maven Central repository.

3. API-modellering

Ettermonter modeller REST-endepunkter som Java-grensesnitt, noe som gjør dem veldig enkle å forstå og konsumere.

Vi modellerer bruker-API fra GitHub; dette har en endepunkt som returnerer dette i JSON-format:

{login: "mojombo", id: 1, url: "//api.github.com/users/mojombo", ...}

Ettermontering fungerer ved å modellere over en grunn-URL og ved å gjøre grensesnitt som returnerer enhetene fra REST-sluttpunktet.

For enkelhets skyld skal vi ta en liten del av JSON ved å modellere vår Bruker klasse som skal ta verdiene når vi har mottatt dem:

public class User {private String login; privat lang id; privat String url; // ... // standard getters an setters}

Vi kan se at vi bare tar et delsett av egenskaper for dette eksemplet. Ettermontering klager ikke over manglende egenskaper - siden det bare kartlegger det vi trenger, det vil ikke engang klage hvis vi skulle legge til egenskaper som ikke er i JSON.

Nå kan vi gå til grensesnittmodellering og forklare noen av ettermonteringsanmerkelsene:

offentlig grensesnitt UserService {@GET ("/ brukere") offentlig samtale getUsers (@Query ("per_page") int per_page, @Query ("page") int side); @GET ("/ brukere / {brukernavn}") offentlig Ring getUser (@Path ("brukernavn") String brukernavn); }

Metadataene som følger med merknader er nok til at verktøyet kan generere arbeidsimplementeringer.

De @FÅ kommentar forteller klienten hvilken HTTP-metode som skal brukes og hvilken ressurs, for eksempel ved å oppgi en grunn-URL på “//api.github.com” vil den sende forespørselen til “//api.github.com/users” .

Den ledende “/” på vår relative URL forteller Retrofit at det er en absolutt vei på verten.

En annen ting å merke seg er at vi bruker helt valgfritt @Spørsmål parametere, som kan sendes som null hvis vi ikke trenger dem, vil verktøyet sørge for å ignorere disse parametrene hvis de ikke har verdier.

Og sist men ikke minst, @Sti kan vi spesifisere en styparameter som skal plasseres i stedet for markeringen vi brukte i stien.

4. Synkron / asynkron API

For å lage en HTTP-forespørselsanrop må vi først bygge vårt ettermonteringsobjekt:

OkHttpClient.Builder httpClient = ny OkHttpClient.Builder (); Ettermontering ettermontering = ny Retrofit.Builder () .baseUrl ("// api.github.com/") .addConverterFactory (GsonConverterFactory.create ()) .client (httpClient.build ()) .build ();

Retrofit gir en praktisk byggherre for å konstruere det nødvendige objektet. Den trenger basis-URL-en som skal brukes for hver serviceanrop og en omformerfabrikk - som tar seg av analysering av data vi sender, og også svarene vi får.

I dette eksemplet skal vi bruke GsonConverterFactory, som skal kartlegge JSON-dataene våre til Bruker klasse vi definerte tidligere.

Det er viktig å merke seg at forskjellige fabrikker tjener forskjellige formål, så husk at vi også kan bruke fabrikker til XML, proto-buffere eller til og med lage en for en tilpasset protokoll. For en liste over allerede implementerte fabrikker, kan vi ta en titt her.

Den siste avhengigheten er OKHttpClient - som er en HTTP & HTTP / 2-klient for Android- og Java-applikasjoner. Dette kommer til å ta vare på tilkobling til serveren og sending og henting av informasjon. Vi kan også legge til overskrifter og avlyttere for hver samtale, som vi skal se i vår autentiseringsdel.

Nå som vi har vårt ettermonteringsobjekt, kan vi konstruere tjenesteanropet vårt, la oss ta en titt på hvordan du gjør dette på den synkrone måten:

UserService service = retrofit.create (UserService.class); Ring callSync = service.getUser ("eugenp"); prøv {Response response = callSync.execute (); Brukerbruker = respons.body (); } fangst (Unntak eks) {...}

Her kan vi se hvordan Retrofit tar seg av konstruksjonen av servicegrensesnittet vårt ved å injisere koden som er nødvendig for å komme med forespørselen, basert på våre tidligere merknader.

Etter det får vi en Anrop objekt som er det som brukes til å utføre forespørselen til GitHub API. Den viktigste metoden her er henrette, som brukes til å utføre en samtale synkront og vil blokkere den gjeldende tråden under overføring av dataene.

Etter at samtalen er fullført, kan vi hente svarteksten - allerede på et brukerobjekt - takket være vår GsonConverterFactory.

Det er veldig enkelt å ringe synkront, men vanligvis bruker vi en ikke-blokkerende asynkron forespørsel:

UserService service = retrofit.create (UserService.class); Ring callAsync = service.getUser ("eugenp"); callAsync.enqueue (ny tilbakeringing () {@Override public void onResponse (Call call, Response response) {User user = response.body ();} @ Override public void onFailure (Call call, Throwable throwable) {System.out.println) (kastbar);}});

Nå i stedet for kjør metoden, bruker vi enqueue metode - som tar en Ring tilbakegrensesnitt som en parameter for å håndtere vellykket eller mislykket forespørsel. Merk at dette vil kjøres i en egen tråd.

Etter at samtalen er fullført, kan vi hente kroppen på samme måte som vi gjorde tidligere.

5. Lage en gjenbrukbar ServiceGenerator Klasse

Nå som vi så hvordan vi skal konstruere vårt ettermonteringsobjekt og hvordan vi bruker et API, kan vi se at vi ikke vil fortsette å skrive byggherren om og om igjen.

Det vi ønsker er en gjenbrukbar klasse som lar oss lage dette objektet en gang og bruke det i løpet av applikasjonen:

offentlig klasse GitHubServiceGenerator {privat statisk sluttstreng BASE_URL = "//api.github.com/"; privat statisk Retrofit.Builder-builder = ny Retrofit.Builder () .baseUrl (BASE_URL) .addConverterFactory (GsonConverterFactory.create ()); privat statisk ettermontering ettermontering = builder.build (); privat statisk OkHttpClient.Builder httpClient = ny OkHttpClient.Builder (); offentlig statisk S createService (Class serviceClass) {return retrofit.create (serviceClass); }}

All logikken med å lage Retrofit-objektet flyttes nå til dette GitHubServiceGenerator klasse, gjør dette det til en bærekraftig klientklasse som hindrer at koden gjentas.

Her er et enkelt eksempel på hvordan du bruker det:

UserService service = GitHubServiceGenerator.createService (UserService.class);

Nå hvis vi for eksempel skulle lage en RepositoryService, vi kunne gjenbruke denne klassen og forenkle skapelsen.

I neste avsnitt, vi skal utvide det og legge til autentiseringsfunksjoner.

6. Autentisering

De fleste API-er har noen autentisering for å sikre tilgang til den.

Tatt i betraktning vår forrige generatorklasse, skal vi legge til en metode for å opprette tjenester som tar et JWT-token med Autorisasjon Overskrift :

offentlig statisk S createService (Class serviceClass, final String token) {if (token! = null) {httpClient.interceptors (). clear (); httpClient.addInterceptor (chain -> {Request original = chain.request (); Request request = original.newBuilder () .header ("Authorization", token) .build (); return chain.proceed (request);}); builder.client (httpClient.build ()); ettermontering = builder.build (); } returner retrofit.create (serviceClass); }

For å legge til en overskrift på forespørselen vår, må vi bruke avlyttingsfunksjonene til OkHttp; vi gjør dette ved å bruke vår tidligere definerte byggmester og ved å rekonstruere Retrofit-objektet.

Merk at dette er et enkelt godkjenningseksempel, men med bruk av avlyttere kan vi bruke hvilken som helst godkjenning som OAuth, bruker / passord, etc.

7. Logging

I denne delen skal vi utvide vår ytterligere GitHubServiceGenerator for loggingsegenskaper, som er veldig viktige for feilsøkingsformål i hvert prosjekt.

Vi skal bruke vår tidligere kunnskap om avlyttere, men vi trenger en ekstra avhengighet, som er HttpLoggingInterceptor fra OkHttp, la oss legge det til vårt pom.xml:

 com.squareup.okhttp3 logging-interceptor 3.9.0 

La oss nå utvide vår GitHubServiceGenerator klasse:

offentlig klasse GitHubServiceGenerator {privat statisk sluttstreng BASE_URL = "//api.github.com/"; privat statisk Retrofit.Builder-builder = ny Retrofit.Builder () .baseUrl (BASE_URL) .addConverterFactory (GsonConverterFactory.create ()); privat statisk ettermontering ettermontering = builder.build (); privat statisk OkHttpClient.Builder httpClient = ny OkHttpClient.Builder (); privat statisk HttpLoggingInterceptor logging = ny HttpLoggingInterceptor () .setLevel (HttpLoggingInterceptor.Level.BASIC); offentlig statisk S createService (Class serviceClass) {if (! httpClient.interceptors (). inneholder (logging)) {httpClient.addInterceptor (logging); builder.client (httpClient.build ()); ettermontering = builder.build (); } returner retrofit.create (serviceClass); } offentlig statisk S createService (Class serviceClass, final String token) {if (token! = null) {httpClient.interceptors (). clear (); httpClient.addInterceptor (chain -> {Request original = chain.request (); Request.Builder builder1 = original.newBuilder () .header ("Authorization", token); Request request = builder1.build (); return chain.proceed) (be om); }); builder.client (httpClient.build ()); ettermontering = builder.build (); } returner retrofit.create (serviceClass); }}

Dette er den endelige formen for klassen vår, vi kan se hvordan vi la til HttpLoggingInterceptor, og vi satte den for grunnleggende logging, som skal logge tiden det tok å sende forespørselen, sluttpunktet, status for hver forespørsel, etc.

Det er viktig å ta en titt på hvordan vi sjekker om interceptor eksisterer, slik at vi ikke tilfeldigvis legger den til to ganger.

8. Konklusjon

I denne omfattende veiledningen tok vi en titt på det utmerkede ettermonteringsbiblioteket ved å fokusere på Sync / Async API, noen gode fremgangsmåter for modellering, autentisering og logging.

Biblioteket kan brukes på svært komplekse og nyttige måter; for en avansert brukstilfelle med RxJava, ta en titt på denne veiledningen.

Og som alltid kan kildekoden bli funnet på GitHub.