Bygg en enkel webapplikasjon med Spring Boot og Groovy

1. Oversikt

Groovy har en rekke funksjoner som vi kanskje vil bruke i vår-nettapplikasjoner.

Så i denne opplæringen bygger vi en enkel todo-applikasjon med Spring Boot og Groovy. Vi vil også utforske integrasjonspunktene deres.

2. Todo-søknad

Applikasjonen vår har følgende funksjoner:

  • Lag oppgave
  • Rediger oppgaven
  • Slett oppgaven
  • Vis spesifikk oppgave
  • Vis alle oppgaver

Det blir en REST-basert applikasjon og vi bruker Maven som vårt byggeverktøy.

2.1. Maven avhengigheter

La oss ta med alle avhengighetene som kreves i vår pom.xml fil:

 org.springframework.boot spring-boot-starter-data-jpa 2.2.6.RELEASE org.springframework.boot spring-boot-starter-web 2.2.6.RELEASE org.codehaus.groovy groovy 3.0.3 org.springframework.boot spring-boot-starter-test 2.2.6.RELEASE test com.h2database h2 1.4.200 runtime 

Her er vi gjelder også spring-boot-starter-web å bygge REST-endepunkter, og importerer groovy avhengighet for å gi Groovy-støtte til prosjektet vårt.

For utholdenhetslaget bruker vi spring-boot-starter-data-jpa, og h2 er den innebygde databasen.

Vi må også inkludere gmavenplus-plugin med alle målene i pom.xml:

  // ... org.codehaus.gmavenplus gmavenplus-plugin 1.9.0 addSources addTestSources generereStubs kompilere generereTestStubs kompilereTester fjerneStubber fjerneTestStubs 

2.2. JPA-enhetsklasse

La oss skrive en enkel Å gjøre Groovy klasse med tre felt - id, oppgave, og det er ferdig:

@Entity @Table (name = 'todo') class Todo {@Id @GeneratedValue (strategy = GenerationType.IDENTITY) Integer id @Column String task @Column Boolean isCompleted}

Her, den id feltet er den unike identifikatoren for oppgaven. oppgave inneholder detaljene i oppgaven og det er ferdig viser om oppgaven er fullført eller ikke.

Legg merke til det, når vi ikke gir tilgangsmodifikatorer til feltet, vil Groovy-kompilatoren gjøre feltet som privat, og vil også generere getter- og settermetoder for det.

2.3. Persistenslaget

La oss lage et Groovy-grensesnitt - TodoRepository som implementerer JpaRepository. Det tar seg av alle CRUD-operasjonene i applikasjonen vår:

@Repository-grensesnitt TodoRepository utvider JpaRepository {}

2.4. Servicelaget

De TodoService grensesnittet inneholder alle de abstrakte metodene som kreves for vår CRUD-operasjon:

grensesnitt TodoService {List findAll () Todo findById (Integer todoId) Todo saveTodo (Todo todo) Todo updateTodo (Todo todo) Todo deleteTodo (Integer todoId)}

De TodoServiceImpl er en implementeringsklasse som implementerer alle metodene for TodoService:

@Service-klasse TodoServiceImpl implementerer TodoService {// ... @Override List findAll () {todoRepository.findAll ()} @Override Todo findById (Integer todoId) {todoRepository.findById todoId get ()} @Override Todo saveTodo {todoRepository.save todo} @Override Todo updateTodo (Todo todo) {todoRepository.save todo} @Override Todo deleteTodo (Integer todoId) {todoRepository.deleteById todoId}}

2.5. Kontrollerlaget

La oss nå definere alle REST API-ene i TodoController som er vår @RestController:

@RestController @RequestMapping ('todo') offentlig klasse TodoController {@Autowired TodoService todoService @GetMapping List getAllTodoList () {todoService.findAll ()} @PostMapping Todo saveTodo (@RequestBody Todo todo) {todoSoToDo.save.support} (@RequestBody Todo todo) {todoService.updateTodo todo} @DeleteMapping ('/ {todoId}') deleteTodo (@PathVariable Integer todoId) {todoService.deleteTodo todoId} @GetMapping ('/ {todoId}') Todo geto Heltall todoId) {todoService.findById todoId}}

Her har vi definert fem sluttpunkter som brukeren kan ringe for å utføre CRUD-operasjoner.

2.6. Bootstrapping Spring Boot Application

La oss nå skrive en klasse med hovedmetoden som skal brukes til å starte søknaden vår:

@SpringBootApplication klasse SpringBootGroovyApplication {static void main (String [] args) {SpringApplication.run SpringBootGroovyApplication, args}}

Legg merke til det, i Groovy er bruk av parentes valgfri når vi kaller en metode ved å sende argumenter - og det er det vi gjør i eksemplet ovenfor.

Også, suffikset .klasse er ikke nødvendig for noen klasse i Groovy det er derfor vi bruker SpringBootGroovyApplication direkte.

La oss nå definere denne klassen i pom.xml som startklasse:

 com.baeldung.app.SpringBootGroovyApplication 

3. Kjøre applikasjonen

Endelig er søknaden vår klar til å kjøres. Vi burde bare kjøre SpringBootGroovyApplication klasse som Java-applikasjonen eller kjør Maven build:

spring-boot: løp

Dette skal starte søknaden på // lokal vert: 8080 og vi skal kunne få tilgang til endepunktene.

4. Testing av applikasjonen

Søknaden vår er klar for testing. La oss lage en Groovy-klasse - TodoAppTest for å teste søknaden vår.

4.1. Førstegangs oppsett

La oss definere tre statiske variabler - API_ROOT, readingTodoId, og writingTodoId i klassen vår:

statisk API_ROOT = "// localhost: 8080 / todo" statisk lesingTodoId statisk skrivingTodoId

Her, den API_ROOT inneholder rotnettadressen til appen vår. De readingTodoId og writingTodoId er hovednøklene til testdataene som vi senere bruker til å utføre testing.

La oss nå lage en annen metode - populateDummyData () ved å bruke kommentaren @BeforeClass for å fylle ut testdataene:

@BeforeClass statisk tomrom populateDummyData () {Todo readingTodo = ny Todo (oppgave: 'Reading', isCompleted: false) Todo writingTodo = new Todo (oppgave: 'Writing', isCompleted: false) final Response readingResponse = RestAssured.given (). contentType (MediaType.APPLICATION_JSON_VALUE) .body (readingTodo) .post (API_ROOT) Todo cookingTodoResponse = readingResponse.as Todo.class readingTodoId = cookingTodoResponse.getId () final Response writingResponse = RestAssured.given (). (writingTodo) .post (API_ROOT) Todo writingTodoResponse = writingResponse.as Todo.class writingTodoId = writingTodoResponse.getId ()}

Vi vil også fylle ut variabler - readingTodoId og writingTodoId i samme metode for å lagre primærnøkkelen til postene vi lagrer.

Legg merke til det, i Groovy kan vi også initialisere bønner ved å bruke navngitte parametere og standardkonstruktøren som vi gjør for bønner som readingTodo og writingTodo i utdraget ovenfor.

4.2. Testing av CRUD-operasjoner

Deretter la oss finne alle oppgavene fra todo-listen:

@Test ugyldig nårGetAllTodoList_thenOk () {final Response response = RestAssured.get (API_ROOT) assertEquals HttpStatus.OK.value (), response.getStatusCode () assertTrue response.as (List.class) .størrelse ()> 0}

La oss så finne en bestemt oppgave ved å passere readingTodoId som vi har fylt ut tidligere:

@Test ugyldig nårGetTodoById_thenOk () {final Response response = RestAssured.get ("$ API_ROOT / $ readingTodoId") assertEquals HttpStatus.OK.value (), response.getStatusCode () Todo todoResponse = respons.as Todo.ass. .getId ()}

Her har vi brukt interpolering for å sammenkoble URL-strengen.

Videre, la oss prøve å oppdatere oppgaven i todo-listen ved hjelp av readingTodoId:

@Test ugyldig nårUpdateTodoById_thenOk () {Todo todo = new Todo (id: readingTodoId, isCompleted: true) final Response response = RestAssured.given () .contentType (MediaType.APPLICATION_JSON_VALUE) .body (todo) .put (API_ROS). OK.value (), response.getStatusCode () Todo todoResponse = respons.as Todo.class assertTrue todoResponse.getIsCompleted ()}

Og deretter slette oppgaven i todo-listen ved hjelp av writingTodoId:

@Test ugyldig nårDeleteTodoById_thenOk () {final Response response = RestAssured.given () .delete ("$ API_ROOT / $ writingTodoId") assertEquals HttpStatus.OK.value (), response.getStatusCode ()}

Endelig kan vi lagre en ny oppgave:

@Test ugyldig nårSaveTodo_thenOk () {Todo todo = new Todo (oppgave: 'Blogging', isCompleted: false) final Response response = RestAssured.given () .contentType (MediaType.APPLICATION_JSON_VALUE) .body (todo) .post (API_ROOT) assertEquals HttpStatus.OK.value (), respons.getStatusCode ()}

5. Konklusjon

I denne artikkelen har vi brukt Groovy og Spring Boot til å bygge et enkelt program. Vi har også sett hvordan de kan integreres sammen og demonstrerte noen av de kule funksjonene i Groovy med eksempler.

Som alltid er hele kildekoden til eksemplet tilgjengelig på GitHub.