RestController con Spring Boot
En este post vamos a revisar un ejemplo sencillo de lo que sería los servicios Rest utilizando Spring Framework. Las tecnologías requeridas para este proyecto son:
- Spring Boot
- H2
- Maven
- JDK 8
A continuación se muestra la estructura del proyecto Maven. En este proyecto, utilizaremos una base de datos H2 la cual podremos manipular a través de tres servicios Rest ya sea para insertar, consultar un registro o listar una tabla.
El archivo POM de dependencias Maven es el siguiente:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.rolandopalermo.git</groupId> <artifactId>base-api-rest-springboot</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.4.0.RELEASE</version> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> </dependency> </dependencies> <build> <finalName>base-api-rest-springboot</finalName> </build> </project>La clase principal utilizada para iniciar Spring Boot es la siguiente:
package com.rolandopalermo.rest.base; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }La siguiente clase representa el bean que será utilizado para manipular nuestra base de datos. Este bean utilizará anotaciones las cuales le permitirán validar la correcta estructura de campos en cualquier instancia así como también manipular este bean como objeto JSON.
package com.rolandopalermo.rest.base.model; import java.util.Date; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.validation.constraints.Max; import javax.validation.constraints.Min; import javax.validation.constraints.NotNull; import javax.validation.constraints.Past; import org.hibernate.validator.constraints.NotBlank; import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonProperty; @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; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public Gender getGender() { return gender; } public void setGender(Gender gender) { this.gender = gender; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public Date getDateOfBirth() { return dateOfBirth; } public void setDateOfBirth(Date dateOfBirth) { this.dateOfBirth = dateOfBirth; } }
package com.rolandopalermo.rest.base.model; public enum Gender { MALE, FEMALE; }
Esta clase se encargá de definir los métodos para acceder a base de datos. En este caso se reutilizará la clase genérica CrudRepository.
package com.rolandopalermo.rest.base.repository; import org.springframework.data.repository.CrudRepository; import com.rolandopalermo.rest.base.model.User; public interface UserRepository extends CrudRepository<User, Long> { }La clase UserService conformará la capa de servicio y es en donde se invocará a los métodos definidos en la clase UserRepository que vendría siendo nuestra capa de datos.
package com.rolandopalermo.rest.base.service; import java.util.ArrayList; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.rolandopalermo.rest.base.model.User; import com.rolandopalermo.rest.base.repository.UserRepository; @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>(); for(User user : users) { list.add(user); } return list; } public User create(User user) { return repository.save(user); } }
La clase UserController expondrá los diversos métodos para manipular la tabla de Usuarios. Estos serán para insertar, consultar un registro o listarlos todos. Estos servicios serán expuestos a través de los métodos POST y GET.
package com.rolandopalermo.rest.base.controller; import java.util.List; import javax.validation.Valid; 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.RestController; import com.rolandopalermo.rest.base.model.User; import com.rolandopalermo.rest.base.service.UserService; @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); } }Al ejecutar el proyecto, tendremos lo siguiente:
Al enviar la siguiente petición utilizando POSTMAN, el resultado será el siguiente:
{ "id":1, "user_name":"Juan", "last_name":"Perez", "gender":"MALE", "age":23, "birth":"12-10-1994" }
Cuando consultemos los registros ingresados, obtendremos lo siguiente:
[ { "id": 1, "user_name": "Juan", "last_name": "Perez", "gender": "MALE", "age": 23, "birth": "12-10-1994" }, { "id": 2, "user_name": "Juan", "last_name": "De Arco", "gender": "FEMALE", "age": 23, "birth": "12-10-1994" } ]
Comentarios
Publicar un comentario