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