Izgradite REST API pomoću Spring i Java Config

OSTALO Vrh

Upravo sam najavio novo Uči proljeće tečaj, usredotočen na osnove Spring 5 i Spring Boot 2:

>> PROVJERITE TEČAJ

1. Pregled

Ovaj članak pokazuje kako postavili REST u proljeće - kodovi odgovora kontrolera i HTTP-a, konfiguracija razvrstavanja korisnog tereta i pregovaranje o sadržaju.

2. Razumijevanje REST-a u proljeće

Proljetni okvir podržava dva načina stvaranja RESTful usluga:

  • koristeći MVC sa ModelAndView
  • pomoću pretvarača HTTP poruka

The ModelAndView Pristup je stariji i puno je bolje dokumentiran, ali također i opširniji i teži u konfiguraciji. Pokušava ukloniti ostalu paradigmu u stari model, što nije bez problema. Proljetni tim je to razumio i pružio je prvoklasnu REST podršku počevši od Spring 3.0.

Novi pristup, zasnovan na HttpMessageConverter i bilješke, puno je lakši i lak za implementaciju. Konfiguracija je minimalna i pruža razumne zadane vrijednosti za ono što biste očekivali od usluge RESTful.

3. Java konfiguracija

@Configuration @EnableWebMvc javna klasa WebConfig {//}

Novi @EnableWebMvc anotacija čini neke korisne stvari - konkretno, u slučaju REST, otkriva postojanje Jacksona i JAXB 2 na putu predavanja te automatski stvara i registrira zadane JSON i XML pretvarače. Funkcionalnost bilješke ekvivalentna je XML verziji:

Ovo je prečac i premda može biti koristan u mnogim situacijama, nije savršen. Kad je potrebna složenija konfiguracija, uklonite napomenu i proširite WebMvcConfigurationSupport direktno.

3.1. Korištenje Spring Boota

Ako koristimo @SpringBootApplication bilješka i proljeće-webmvc knjižnica je na stazi, a zatim @EnableWebMvc napomena se dodaje automatski sa zadanom automatskom konfiguracijom.

I dalje možemo dodati MVC funkcionalnost u ovu konfiguraciju implementirajući WebMvcConfigurer sučelje na a @Konfiguracija komentirani razred. Također možemo koristiti i WebMvcRegistrationsAdapter primjerice pružiti svoje RequestMappingHandlerMapping, RequestMappingHandlerAdapter, ili ExceptionHandlerExceptionResolver implementacije.

Napokon, ako želimo odbaciti MVC značajke Spring Boota i proglasiti prilagođenu konfiguraciju, to možemo učiniti pomoću @EnableWebMvc bilješka.

4. Testiranje proljetnog konteksta

Počevši od proljeća 3.1, dobivamo prvoklasnu podršku za testiranje @Konfiguracija klase:

@RunWith (SpringJUnit4ClassRunner.class) @ContextConfiguration (classes = {WebConfig.class, PersistenceConfig.class}, loader = AnnotationConfigContextLoader.class) javna klasa SpringContextIntegrationTest {@Test public void context {@Test public void context {@Test public void context {@Test public void context {@Test public void context {@Test public void context {@Test public void context {Lotest void context

Specificiramo klase Java konfiguracije s @ContextConfiguration bilješka. Novi AnnotationConfigContextLoader učitava definicije graha iz @Konfiguracija razreda.

Primijetite da WebConfig klasa konfiguracije nije bila uključena u test, jer se treba izvoditi u kontekstu Servleta, što nije predviđeno.

4.1. Korištenje Spring Boota

Spring Boot nudi nekoliko bilješki za postavljanje Springa ApplicationContext za naše testove na intuitivniji način.

Možemo učitati samo određeni dio konfiguracije aplikacije ili možemo simulirati cijeli postupak pokretanja konteksta.

Na primjer, možemo koristiti @SpringBootTest napomena ako želimo da se cijeli kontekst kreira bez pokretanja poslužitelja.

Uz to na mjestu, možemo dodati znak @AutoConfigureMockMvc ubrizgati a MockMvc instance i pošaljite HTTP zahtjeve:

@RunWith (SpringRunner.class) @SpringBootTest @AutoConfigureMockMvc javna klasa FooControllerAppIntegrationTest {@Autowired private MockMvc mockMvc; @Test public void whenTestApp_thenEmptyResponse () baca iznimku {this.mockMvc.perform (get ("/ foos") .andExpect (status (). IsOk ()). And Expect (...);}}

Možemo koristiti kako bismo izbjegli stvaranje cjelokupnog konteksta i testirali samo naše MVC kontrolere @WebMvcTest:

@RunWith (SpringRunner.class) @WebMvcTest (FooController.class) javna klasa FooControllerWebLayerIntegrationTest {@Autowired private MockMvc mockMvc; @MockBean privatna usluga IFooService; @Test () javna praznina kadaTestMvcController_thenRetrieveExpectedResult () baca izuzetak {// ... this.mockMvc.perform (get ("/ foos") .andExpect (...);}}

Detaljne informacije o ovoj temi možemo pronaći u našem članku "Testiranje u proljetnom pokretanju".

5. Kontroler

The @RestController središnji je artefakt u cijelom web stupnju API-ja RESTful. U svrhu ovog posta, kontrolor modelira jednostavan REST resurs - Foo:

@RestController @RequestMapping ("/ foos") klasa FooController {@Autowired privatna usluga IFooService; @GetMapping javni popis findAll () {return service.findAll (); } @GetMapping (value = "/ {id}") javni Foo findById (@PathVariable ("id") Long id) {return RestPreconditions.checkFound (service.findById (id)); } @PostMapping @ResponseStatus (HttpStatus.CREATED) javni Dugo stvaranje (resurs @RequestBody Foo) {Preconditions.checkNotNull (resurs); return service.create (resurs); } @PutMapping (value = "/ {id}") @ResponseStatus (HttpStatus.OK) javno void ažuriranje (@PathVariable ("id") Long id, @RequestBody Foo resurs) {Preconditions.checkNotNull (resource); RestPreconditions.checkNotNull (service.getById (resource.getId ())); service.update (resurs); } @DeleteMapping (value = "/ {id}") @ResponseStatus (HttpStatus.OK) javno prazno brisanje (@PathVariable ("id") Long id) {service.deleteById (id); }}

Možda ste primijetili da se služim izravnim stilom u Guavi Preduvjeti za odmor korisnost:

javna klasa RestPreconditions {javni statički T checkFound (T resurs) {if (resource == null) {throw new MyResourceNotFoundException (); } povratni resurs; }}

Implementacija kontrolera nije javna - to je zato što to ne treba biti.

Obično je kontroler posljednji u lancu ovisnosti. Prima HTTP zahtjeve od proljetnog prednjeg kontrolera ( DispatcherServlet) i jednostavno ih delegira na prosljeđivanje sloju usluge. Ako nema korisnog slučaja kada se kontroler mora ubrizgati ili njime manipulirati izravnom referencom, onda radije ne bih ga proglašavao javnim.

Mapiranja zahtjeva su jednostavna. Kao i kod svakog kontrolera, stvarni vrijednost mapiranja, kao i HTTP metoda, određuju ciljnu metodu za zahtjev. @RequestBody će povezati parametre metode s tijelom HTTP zahtjeva, dok @ResponseBody čini isto za tip odgovora i povratka.

The @RestController je stenografija koja uključuje oba @ResponseBody i @Controller bilješke u našem razredu.

Oni također osiguravaju da će resurs biti marširan i demarširan pomoću ispravnog HTTP pretvarača. Pregovaranje o sadržaju održat će se kako bi se odabralo koji će se od aktivnih pretvarača koristiti, uglavnom na temelju Prihvatiti zaglavlje, iako se i druga HTTP zaglavlja mogu koristiti za određivanje zastupljenosti.

6. Mapiranje HTTP kodova odgovora

Statusni kodovi HTTP odgovora jedan su od najvažnijih dijelova REST usluge, a predmet može brzo postati vrlo kompliciran. Ispravljanje ovih ispravnosti može biti ono što čini ili narušava uslugu.

6.1. Nekartirani zahtjevi

Ako Spring MVC primi zahtjev koji nema mapiranje, on smatra da zahtjev nije dopušten i vraća klijentu 405 METODU NE DOZVOLJENU.

Također je dobra praksa uključiti Dopustite HTTP zaglavlje prilikom vraćanja a 405 klijentu, da navede koje su operacije dopuštene. Ovo je standardno ponašanje Spring MVC-a i ne zahtijeva dodatnu konfiguraciju.

6.2. Važeći mapirani zahtjevi

Za bilo koji zahtjev koji ima mapiranje, Spring MVC smatra zahtjev valjanim i odgovara s 200 OK ako nijedan drugi statusni kôd nije drugačije naveden.

Zbog toga upravljač izjavljuje drugačije @ResponseStatus za stvoriti, ažuriranje i izbrisati akcije, ali ne i za dobiti, koji bi doista trebao vratiti zadanih 200 u redu.

6.3. Pogreška klijenta

U slučaju pogreške klijenta, prilagođene iznimke definiraju se i preslikavaju u odgovarajuće kodove pogrešaka.

Jednostavno bacanje ovih izuzetaka iz bilo kojeg od slojeva web razine osigurat će proljeće mapiranju odgovarajućeg statusnog koda na HTTP odgovoru:

@ResponseStatus (HttpStatus.BAD_REQUEST) javna klasa BadRequestException proširuje RuntimeException {//} @ResponseStatus (HttpStatus.NOT_FOUND) javna klasa ResourceNotFoundException proširuje RuntimeException {//}

Te su iznimke dio REST API-ja i kao takve trebale bi se koristiti samo u odgovarajućim slojevima koji odgovaraju REST-u; ako na primjer postoji sloj DAO / DAL, on ne bi trebao izravno koristiti iznimke.

Također imajte na umu da ovo nisu provjerene iznimke već iznimke u vrijeme izvođenja - u skladu s proljetnim praksama i idiomima.

6.4. Koristeći @ExceptionHandler

Druga mogućnost mapiranja prilagođenih iznimaka na određene statusne kodove je upotreba @ExceptionHandler napomena u upravljaču. Problem s tim pristupom je taj što se napomena odnosi samo na kontroler u kojem je definirana. To znači da se moramo izjasniti u svakom kontroloru pojedinačno.

Naravno, postoji više načina za rješavanje pogrešaka i u Spring i u Spring Boot koji nude veću fleksibilnost.

7. Dodatne ovisnosti Mavena

Uz to proljeće-webmvc ovisnost potrebna za standardnu ​​web aplikaciju, morat ćemo postaviti marširanje i uklanjanje marširanja sadržaja za REST API:

  com.fasterxml.jackson.core jackson-databind 2.9.8 javax.xml.bind jaxb-api 2.3.1 runtime 

To su knjižnice koje se koriste za pretvaranje predstavljanja resursa REST u JSON ili XML.

7.1. Korištenje Spring Boota

Ako želimo dohvatiti resurse oblikovane u JSON-u, Spring Boot pruža podršku za različite knjižnice, naime Jackson, Gson i JSON-B.

Automatska konfiguracija provodi se uključivanjem bilo koje knjižnice mapiranja u put predavanja.

Obično, ako razvijamo web aplikaciju, samo ćemo dodati proljeće-boot-starter-web ovisnost i osloniti se na to da u naš projekt uključi sve potrebne artefakte:

 org.springframework.boot spring-boot-starter-web 2.1.2.OSLOBODI 

Spring Boot prema zadanim postavkama koristi Jackson.

Ako želimo serializirati svoje resurse u XML formatu, morat ćemo dodati Jackson XML proširenje (jackson-dataformat-xml) prema našim ovisnostima ili zamjenski za implementaciju JAXB-a (prema zadanim postavkama u JDK-u) pomoću @XmlRootElement napomena na našem resursu.

8. Zaključak

Ovaj je vodič ilustrirao kako implementirati i konfigurirati REST uslugu pomoću Spring i Java konfiguracije.

U sljedećim člancima serije usredotočit ću se na mogućnost otkrivanja API-ja, napredno pregovaranje o sadržaju i rad s dodatnim prikazima Resurs.

Sav kôd ovog članka dostupan je na Githubu. Ovo je projekt zasnovan na Mavenu, pa bi ga trebalo lako uvesti i pokrenuti kakav jest.

OSTALO dno

Upravo sam najavio novo Uči proljeće tečaj, usredotočen na osnove Spring 5 i Spring Boot 2:

>> PROVJERITE TEČAJ