Construyendo una aplicación web simple con Spring Boot y Groovy

1. Información general

Groovy tiene varias capacidades que podríamos querer usar en nuestras aplicaciones web Spring.

Entonces, en este tutorial, crearemos una aplicación de tareas simple con Spring Boot y Groovy. Además, exploraremos sus puntos de integración.

2. Aplicación Todo

Nuestra aplicación tendrá las siguientes características:

  • Crear tarea
  • Editar tarea
  • Eliminar tarea
  • Ver tarea específica
  • Ver todas las tareas

Será una aplicación basada en REST y usaremos Maven como nuestra herramienta de construcción .

2.1. Dependencias de Maven

Incluyamos todas las dependencias requeridas en nuestro archivo pom.xml :

 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 

Aquí, estamos incluyendo muelle de arranque-motor de arranque en la web a los puntos finales REST acumulación , y de importar el maravilloso dependencia para proporcionar apoyo a nuestro proyecto maravilloso .

Para la capa de persistencia, usamos spring-boot-starter-data-jpa , y h2 es la base de datos integrada .

Además, tenemos que incluir gmavenplus-plugin con todos los objetivos en pom.xml:

  //...  org.codehaus.gmavenplus gmavenplus-plugin 1.9.0    addSources addTestSources generateStubs compile generateTestStubs compileTests removeStubs removeTestStubs      

2.2. Clase de entidad JPA

Escribamos una clase simple de Todo Groovy con tres campos: id , tarea e isCompleted :

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

Aquí, el campo id es el identificador único de la tarea. task contiene los detalles de la tarea y isCompleted muestra si la tarea se completó o no.

Observe que, cuando no proporcionamos modificadores de acceso al campo, entonces el compilador Groovy hará que ese campo sea privado y también generará métodos getter y setter para él .

2.3. La capa de persistencia

Vamos a crear una interfaz maravillosa - TodoRepository que implementa JpaRepository . Se encargará de todas las operaciones CRUD en nuestra aplicación:

@Repository interface TodoRepository extends JpaRepository {}

2.4. La capa de servicio

La interfaz de TodoService contiene todos los métodos abstractos necesarios para nuestra operación CRUD :

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

El TodoServiceImpl es una clase de implementación que implementa todos los métodos de TodoService:

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

2.5. La capa del controlador

Ahora, definamos todas las API REST en TodoController, que es nuestro @RestController :

@RestController @RequestMapping('todo') public class TodoController { @Autowired TodoService todoService @GetMapping List getAllTodoList(){ todoService.findAll() } @PostMapping Todo saveTodo(@RequestBody Todo todo){ todoService.saveTodo todo } @PutMapping Todo updateTodo(@RequestBody Todo todo){ todoService.updateTodo todo } @DeleteMapping('/{todoId}') deleteTodo(@PathVariable Integer todoId){ todoService.deleteTodo todoId } @GetMapping('/{todoId}') Todo getTodoById(@PathVariable Integer todoId){ todoService.findById todoId } }

Aquí, hemos definido cinco puntos finales a los que el usuario puede llamar para realizar operaciones CRUD.

2.6. Bootstrapping de la aplicación Spring Boot

Ahora, escriba una clase con el método principal que se utilizará para iniciar nuestra aplicación:

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

Note que, en Groovy, el uso de paréntesis es opcional cuando se llama a un método pasando argumentos, y esto es lo que estamos haciendo en el ejemplo anterior.

Además, el sufijo .class no es necesario para ninguna clase en Groovy , por eso estamos usando SpringBootGroovyApplication directamente.

Ahora, definamos esta clase en pom.xml como start-class :

 com.baeldung.app.SpringBootGroovyApplication 

3. Ejecución de la aplicación

Finalmente, nuestra aplicación está lista para ejecutarse. Simplemente deberíamos ejecutar la clase SpringBootGroovyApplication como la aplicación Java o ejecutar la compilación de Maven:

spring-boot:run

Esto debería iniciar la aplicación en // localhost: 8080 y deberíamos poder acceder a sus puntos finales.

4. Prueba de la aplicación

Nuestra aplicación está lista para ser probada. Creemos una clase Groovy - TodoAppTest para probar nuestra aplicación.

4.1. Configuración inicial

Let's define three static variables – API_ROOT, readingTodoId, and writingTodoId in our class:

static API_ROOT = "//localhost:8080/todo" static readingTodoId static writingTodoId

Here, the API_ROOT contains the root URL of our app. The readingTodoId and writingTodoId are the primary keys of our test data which we'll use later to perform testing.

Now, let's create another method – populateDummyData() by using the annotation @BeforeClass to populate the test data:

@BeforeClass static void populateDummyData() { Todo readingTodo = new Todo(task: 'Reading', isCompleted: false) Todo writingTodo = new Todo(task: '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() .contentType(MediaType.APPLICATION_JSON_VALUE) .body(writingTodo).post(API_ROOT) Todo writingTodoResponse = writingResponse.as Todo.class writingTodoId = writingTodoResponse.getId() }

We'll also populate variables – readingTodoId and writingTodoId in the same method to store the primary key of the records we're saving.

Notice that, in Groovy we can also initialize beans by using named parameters and the default constructor like we're doing for beans like readingTodo and writingTodo in the above snippet.

4.2. Testing CRUD Operations

Next, let's find all the tasks from the todo list:

@Test void whenGetAllTodoList_thenOk(){ final Response response = RestAssured.get(API_ROOT) assertEquals HttpStatus.OK.value(),response.getStatusCode() assertTrue response.as(List.class).size() > 0 }

Then, let's find a specific task by passing readingTodoId which we've populated earlier:

@Test void whenGetTodoById_thenOk(){ final Response response = RestAssured.get("$API_ROOT/$readingTodoId") assertEquals HttpStatus.OK.value(),response.getStatusCode() Todo todoResponse = response.as Todo.class assertEquals readingTodoId,todoResponse.getId() }

Here, we've used interpolation to concatenate the URL string.

Furthermore, let's try to update the task in the todo list by using readingTodoId:

@Test void whenUpdateTodoById_thenOk(){ Todo todo = new Todo(id:readingTodoId, isCompleted: true) final Response response = RestAssured.given() .contentType(MediaType.APPLICATION_JSON_VALUE) .body(todo).put(API_ROOT) assertEquals HttpStatus.OK.value(),response.getStatusCode() Todo todoResponse = response.as Todo.class assertTrue todoResponse.getIsCompleted() }

And then delete the task in the todo list by using writingTodoId:

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

Finally, we can save a new task:

@Test void whenSaveTodo_thenOk(){ Todo todo = new Todo(task: 'Blogging', isCompleted: false) final Response response = RestAssured.given() .contentType(MediaType.APPLICATION_JSON_VALUE) .body(todo).post(API_ROOT) assertEquals HttpStatus.OK.value(),response.getStatusCode() }

5. Conclusion

En este artículo, hemos utilizado Groovy y Spring Boot para crear una aplicación sencilla. También hemos visto cómo se pueden integrar juntos y hemos demostrado algunas de las características interesantes de Groovy con ejemplos.

Como siempre, el código fuente completo del ejemplo está disponible en GitHub.