Uvod u nadogradnju

1. Pregled

Retrofit je HTTP klijent koji je siguran za tip za Android i Javu - razvio ga je Square (Dagger, Okhttp).

U ovom ćemo članku objasniti kako koristiti Retrofit s naglaskom na njegove najzanimljivije značajke. Značajnije ćemo razgovarati o sinkronom i asinkronom API-ju, kako ga koristiti s autentifikacijom, evidentiranjem i neke dobre prakse modeliranja.

2. Postavljanje primjera

Za početak ćemo dodati Retrofit knjižnicu i Gson pretvarač:

 com.squareup.retrofit2 retrofit 2.3.0 com.squareup.retrofit2 pretvarač-gson 2.3.0 

Za najnovije verzije, pogledajte Retrofit i converter-gson na spremištu Maven Central.

3. API modeliranje

Retrofit modelira REST krajnje točke kao Java sučelja, što ih čini vrlo jednostavnim za razumijevanje i upotrebu.

Modelirat ćemo korisnički API iz GitHub-a; ovo ima DOBITI krajnja točka koja ovo vraća u JSON formatu:

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

Retrofit funkcionira modeliranjem preko osnovnog URL-a i čineći da sučelja vraćaju entitete iz REST krajnje točke.

Radi jednostavnosti uzeti ćemo mali dio JSON-a modelirajući naš Korisnik razred koji će poprimiti vrijednosti kad ih primimo:

javna klasa Korisnik {private String prijava; privatni dugi ID; private String url; // ... // standardni dobivači i postavljači}

Vidimo da za ovaj primjer uzimamo samo podskup svojstava. Retrofit se neće žaliti na nedostajuća svojstva - jer mapira samo ono što nam treba, neće se niti žaliti ako bismo dodali svojstva koja nisu u JSON-u.

Sada možemo prijeći na modeliranje sučelja i objasniti neke od napomena o nadogradnji:

javno sučelje UserService {@GET ("/ users") javni poziv getUsers (@Query ("per_page") int per_page, @Query ("page") int page); @GET ("/ users / {username}") javni poziv getUser (@Path ("username") String korisničko ime); }

Metapodaci isporučeni s bilješkama dovoljni su da alat generira radne implementacije.

The @DOBITI napomena klijentu govori koju HTTP metodu treba koristiti i na kojem resursu, pa će, na primjer, davanjem osnovnog URL-a „//api.github.com“ poslati zahtjev na „//api.github.com/users“ .

Vodeća "/" na našem relativnom URL-u govori Retrofit-u da je to apsolutni put na hostu.

Još jedna stvar koju treba napomenuti jest da koristimo potpuno neobavezno @Query parametara, koji se mogu proslijediti kao nuli ako nam nisu potrebni, alat će se pobrinuti za ignoriranje tih parametara ako nemaju vrijednosti.

I posljednje, ali ne najmanje važno, @Staza dopuštamo da odredimo parametar puta koji će biti postavljen umjesto oznaka koje smo koristili u stazi.

4. Sinkroni / asinkroni API

Da bismo konstruirali poziv HTTP zahtjeva, prvo moramo izgraditi svoj objekt Retrofit:

OkHttpClient.Builder httpClient = novi OkHttpClient.Builder (); Retrofit retrofit = new Retrofit.Builder () .baseUrl ("// api.github.com/") .addConverterFactory (GsonConverterFactory.create ()) .client (httpClient.build ()) .build ();

Retrofit nudi prikladan graditelj za izgradnju našeg potrebnog objekta. Potreban mu je osnovni URL koji će se koristiti za svaki servisni poziv i tvornicu pretvarača - koja se brine za raščlanjivanje podataka koje šaljemo, kao i za odgovore koje dobivamo.

U ovom ćemo primjeru koristiti GsonConverterFactory, koji će preslikati naše JSON podatke na Korisnik razred koji smo ranije definirali.

Važno je napomenuti da različite tvornice imaju različite svrhe, pa imajte na umu da tvornice također možemo koristiti za XML, proto-međuspremnike ili čak stvoriti jednu za prilagođeni protokol. Popis već implementiranih tvornica možemo pogledati ovdje.

Posljednja ovisnost je OKHttpClient - koji je HTTP i HTTP / 2 klijent za Android i Java programe. Ovo će se pobrinuti za povezivanje s poslužiteljem te za slanje i preuzimanje podataka. Također bismo mogli dodati zaglavlja i presretače za svaki poziv, što ćemo vidjeti u našem odjeljku za provjeru autentičnosti.

Sad kad imamo svoj objekt Retrofit, možemo konstruirati svoj servisni poziv, pogledajmo kako to učiniti sinkroni:

Usluga UserService = retrofit.create (UserService.class); Nazovite callSync = service.getUser ("eugenp"); pokušajte {Odgovor odgovora = callSync.execute (); Korisnik korisnik = response.body (); } catch (Iznimka ex) {...}

Ovdje možemo vidjeti kako se Retrofit brine za izgradnju našeg sučelja usluge ubrizgavanjem koda potrebnog za podnošenje zahtjeva, na temelju naših prethodnih napomena.

Nakon toga dobivamo a Poziv objekt koji se koristi za izvršavanje zahtjeva za GitHub API. Ovdje je najvažnija metoda izvršiti, koja se koristi za sinkronizirano izvršavanje poziva i blokirat će trenutnu nit tijekom prijenosa podataka.

Nakon što se poziv uspješno izvrši, možemo dohvatiti tijelo odgovora - već na korisničkom objektu - zahvaljujući našem GsonConverterFactory.

Upućivanje sinkronog poziva vrlo je jednostavno, ali obično koristimo neblokirajući asinkroni zahtjev:

Usluga UserService = retrofit.create (UserService.class); Nazovite callAsync = service.getUser ("eugenp"); callAsync.enqueue (novi povratni poziv () {@Override public void onResponse (call call, Response response) {User user = response.body ();} @Override public void onFailure (call call, Throwable throwable) {System.out.println (za bacanje);}});

Sada umjesto metode izvršavanja koristimo enqueue metoda - koja traje a Uzvratiti pozivsučelje kao parametar za obradu uspjeha ili neuspjeha zahtjeva. Imajte na umu da će se ovo izvršiti u zasebnoj niti.

Nakon što je poziv uspješno završen, možemo dohvatiti tijelo na isti način kao i prije.

5. Izrada višekratne upotrebe ServiceGenerator Razred

Sad kad smo vidjeli kako konstruirati svoj objekt Retrofit i kako konzumirati API, možemo vidjeti da ne želimo stalno pisati graditelj iznova i iznova.

Ono što želimo je klasa za višekratnu upotrebu koja nam omogućuje da jednom napravimo ovaj objekt i ponovno ga koristimo za život naše aplikacije:

javna klasa GitHubServiceGenerator {private static final String BASE_URL = "//api.github.com/"; privatni statički graditelj Retrofit.Builder = novi Retrofit.Builder () .baseUrl (BASE_URL) .addConverterFactory (GsonConverterFactory.create ()); privatna statička nadogradnja retrofit = builder.build (); privatni statički OkHttpClient.Builder httpClient = novi OkHttpClient.Builder (); javna statička S createService (Class serviceClass) {return retrofit.create (serviceClass); }}

Sva logika stvaranja objekta Retrofit sada je premještena na ovo GitHubServiceGenerator klase, to je čini održivom klijentskom klasom koja zaustavlja ponavljanje koda.

Evo jednostavnog primjera kako ga koristiti:

Usluga korisničke usluge = GitHubServiceGenerator.createService (UserService.class);

Sad, ako bismo, na primjer, trebali stvoriti RepositoryService, mogli bismo ponovno upotrijebiti ovu klasu i pojednostaviti stvaranje.

U sljedećem odjeljku, proširit ćemo ga i dodati mogućnosti provjere autentičnosti.

6. Autentifikacija

Većina API-ja ima određenu autentifikaciju da bi joj se osigurao pristup.

Uzimajući u obzir našu prethodnu klasu generatora, dodati ćemo metodu kreiranja usluge koja uzima JWT token s Ovlaštenje Zaglavlje :

javna statička S createService (Class serviceClass, završni niz znakova) {if (token! = null) {httpClient.interceptors (). clear (); httpClient.addInterceptor (lanac -> {Zahtjev original = chain.request (); Zahtjev zahtjeva = original.newBuilder () .header ("Ovlaštenje", žeton) .build (); povrat lanca.proces (zahtjev);}); builder.client (httpClient.build ()); retrofit = builder.build (); } vratiti retrofit.create (serviceClass); }

Da bismo našem zahtjevu dodali zaglavlje, trebamo koristiti mogućnosti presretača OkHttp; to radimo pomoću našeg prethodno definiranog graditelja i rekonstrukcijom objekta Retrofit.

Imajte na umu da je ovo jednostavan primjer autorizacije, ali uz upotrebu presretača možemo koristiti bilo koju provjeru autentičnosti poput OAuth, korisnika / lozinke itd.

7. Sječa drva

U ovom ćemo odjeljku dodatno proširiti naš GitHubServiceGenerator za mogućnosti bilježenja, koje su vrlo važne za uklanjanje pogrešaka u svakom projektu.

Koristit ćemo svoje prethodno znanje o presretačima, ali trebamo dodatnu ovisnost, koja je HttpLoggingInterceptor od OkHttp-a, dodajmo ga na naš pom.xml:

 com.squareup.okhttp3 prijamnik-presretač 3.9.0 

Sada produžimo naše GitHubServiceGenerator razred:

javna klasa GitHubServiceGenerator {private static final String BASE_URL = "//api.github.com/"; privatni statički graditelj Retrofit.Builder = novi Retrofit.Builder () .baseUrl (BASE_URL) .addConverterFactory (GsonConverterFactory.create ()); privatna statička nadogradnja retrofit = builder.build (); privatni statički OkHttpClient.Builder httpClient = novi OkHttpClient.Builder (); privatni statički zapisnik HttpLoggingInterceptor = novi HttpLoggingInterceptor () .setLevel (HttpLoggingInterceptor.Level.BASIC); javna statička S createService (Class serviceClass) {if (! httpClient.interceptors (). sadrži (prijavljivanje)) {httpClient.addInterceptor (zapisivanje); builder.client (httpClient.build ()); retrofit = builder.build (); } vratiti retrofit.create (serviceClass); } javni statički S createService (Class serviceClass, završni niz znakova) {if (token! = null) {httpClient.interceptors (). clear (); httpClient.addInterceptor (lanac -> {Zahtjev original = chain.request (); Request.Builder builder1 = original.newBuilder () .header ("Autorizacija", žeton); Zahtjev zahtjeva = builder1.build (); povrat lanca.nastavi (zahtjev);}); builder.client (httpClient.build ()); retrofit = builder.build (); } vratiti retrofit.create (serviceClass); }}

Ovo je konačni oblik našeg predavanja, možemo vidjeti kako smo dodali HttpLoggingInterceptori postavili smo ga za osnovnu evidenciju, koja će evidentirati vrijeme potrebno za podnošenje zahtjeva, krajnju točku, status svakog zahtjeva itd.

Važno je pogledati kako provjeravamo postoji li presretač, kako ga slučajno ne bismo dodali dva puta.

8. Zaključak

U ovom opsežnom vodiču pogledali smo izvrsnu knjižnicu za nadogradnju usredotočivši se na njezin Sync / Async API, neke najbolje prakse modeliranja, provjere autentičnosti i zapisivanja.

Knjižnica se može koristiti na vrlo složene i korisne načine; za napredni slučaj upotrebe s RxJavom, pogledajte ovaj vodič.

Kao i uvijek, izvorni kod možete pronaći na GitHubu.