Spring Boot Rest – Ejemplo RestController con RequestBody y Valid

Para este ejemplo desarrollarás una pequeña aplicación que recibirá un post con un body en json para crear un User mediante un rest api, también tendrás la opción de consultar los User guardados en la BD.

Para definir un RestController en Spring Boot debes anotar tu controlador como un @RestController y anotar cada método que responderá con @RequestMapping.

Spring hace uso de la anotación @RequestBody para mapear el json y la anotación @Valid para aplicar los constraints definidos en la clase para el caso de los post.

  • El endpoint /create recibirá un json con el User, lo validará y lo guardará en la BD.
  • Crearemos otro endopoint /users para consultar todos los User en la BD
  • También un /user?id=userId para mostrar un User por el id
  • Este endpoint para crear, recibirá el json y lo mapeará contra el pojo User

Configurar las dependencias

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
        </dependency>
</dependencies>

Como configurar la Base de datos

El pom definiste una base de datos h2 que correrá embebida en la applicación, en nuestro caso persistirá solamente en memoria.

¿Cómo definir una base de datos H2 en memoria en Spring?

Para que la base de datos h2 persista solo en memoria debemos indicar el datasource en el application.properties de este modo:

#in memory database
spring.datasource.url = jdbc:h2:mem:example_db

#in file database
#spring.datasource.url = jdbc:h2:file:~example_db

spring.datasource.username=sa
spring.datasource.password=
spring.datasource.driver-class-name=org.h2.Driver

Configurar la app para Spring Boot


@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

}

Creas el modelo User

En el modelo que soporta nuestro json desde el post agrega los json property @JsonProperty indicando cómo deberá entenderse cada atributo del json. Además anotas las validaciones que deseas. Para este ejemplo, este mismo modelo lo usaremos para la persistencia por eso lo anotamos como @Entity.

Algunas de las validaciones que para este ejemplo son

  • @NotNull : verifica que el valor no quede nulo.
  • @NotBlank : verifica que el valor sea nulo o blanco para Strings.
  • @Past : verifica que el valor esté en el pasado.
  • @Min : valor mínimo posible.
  • @Max : valor máximo posible.
  • @Email : verifica que el string tenga un formato de email valido.

@Entity
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @JsonProperty("user_name")
    @NotBlank
    private String userName;

    @JsonProperty("last_name")
    @NotBlank
    private String lastName;

    @JsonProperty("gender")
    @NotNull
    private Gender gender;

    @JsonProperty("age")
    @Min(value = 18)
    @Max(value = 150)
    @NotNull
    private Integer age;

    @JsonProperty("birth")
    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd-MM-yyyy")
    @Past
    @NotNull
    private Date dateOfBirth;

   // get and set... 

}

package com.gp.model;
public enum Gender {
    MALE, FEMALE;
}

Creas el servicio y el repository

Tu servicio recibirá las consultas desde el controller y la resolverá lógica del negocio, para el caso del acceso a la base este servicio consultará al repositorio especifico.

@Service
public class UserService {

    @Autowired
    private UserRepository repository;

    public User get(long userId) {
        return repository.findOne(userId);
    }

    public List<User> list() {
        Iterable<User> users = repository.findAll();
        List<User> list = new ArrayList<User>();
        users.forEach(list::add);
        return list;
    }

    public User create(User user) {
        return repository.save(user);
    }
}

El repositorio será un CrudRespository que nos da lo básico para este ejemplo.


import com.gp.model.User;
import org.springframework.data.repository.CrudRepository;

public interface UserRepository extends CrudRepository<User, Long> {

}

Definir un RestController con Spring Boot

Para crear un endpoint a fin de consultar Users y crearlos debes definir un controller de este modo usando las anotaciones @RestController y @RequestMapping

package com.gp.controllers;

import com.gp.model.User;
import com.gp.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.util.List;

@RestController
public class UserController {

    @Autowired
    private UserService userService;

    @RequestMapping(value = "/users", method = RequestMethod.GET)
    public ResponseEntity<User> list() {
        List<User> users = userService.list();
        return new ResponseEntity(users, HttpStatus.OK);
    }

    @RequestMapping(value = "/user", method = RequestMethod.GET)
    public ResponseEntity<User> userById(@RequestParam(value = "id") long id) {
        User user = userService.get(id);
        return new ResponseEntity(user, HttpStatus.OK);
    }

    @RequestMapping(value = "/create", method = RequestMethod.POST)
    public ResponseEntity<User> create(@Valid @RequestBody User user) {
        User userCreated = userService.create(user);
        return new ResponseEntity(userCreated, HttpStatus.CREATED);
    }

}

Pruebas RestController con @Valid y @RequestBody

Prueba enviar tu json con un valor inválido:

Envía al rest /create vía post este body que contiene un valor invalido para el “age”.

Observa la respuesta con un status 400 por no haber pasado los constraint del modelo.

SpringBoot

Prueba con valores válidos:

Ahora envía el json con todos lo valores correctos, el endpoint te devuelve el modelo que creado ya con un id asignado.

SpringBoot

Consulta de todos los User guardados:

Mediante el el endpoint /users podemos obtener toda la lista de User que hemos ido creando.

SpringBoot

Descarga este código completo

Hi! If you find my posts helpful, please support me by inviting me for a coffee :)

Ver también