Anteriormente vimos como guardar y buscar información en nuestra base de datos mediante Hibernate y JPA, utilizando un objeto DAO que igualmente es un servicio de Spring.
Ahora toca utilizar otro tipo de bean especial de Spring, llamado @RestController.
Esta clase será la encargada de atender las llamadas a nuestra API REST.
Para crear el controlador REST de Spring, damos click derecho en el proyecto y vamos a New -> Class
Lo llamaremos TodoController y su paquete será el com.todo.controller y damos click en Finish
.
Agregaremos la anotación @RestController a la declaración de nuestra clase.
Y después la anotación @RequestMapping y le pasaremos un String con todos
que será la ruta en la que este controlador responderá.
En nuestro controlador debemos inyectar el servicio de Spring que creamos anteriormente llamado TodoDao, para esto usaremos la anotación @AutoWired.
Ahora crearemos de uno por uno los métodos para guardar, buscar, actualizar y borrar nuestros Todos desde llamadas a nuestra API REST.
El método para guardar se llamara saveTodo, recibirá un Todo con la anotación @RequestBody y regresara un Todo, también tendrá la anotación RequestMapping y en lugar de pasar un String se pasara en su propiedad method el RequestMethod POST.
Dentro de el utilizaremos el TodoDao y lo retornaremos con su ejecución del método save pasando el Todo que recibimos.
Para probar que el método funciona podemos utilizar un extensión llamada restclient, de la siguiente forma.
Al abrir restclient vamos a la sección del menú Headers y damos click para desplegar lo y seleccionar Custom Header.
En name escribimos Content-Type
y en value application/json
, marcamos Save to favorite y presionamos okay
El valor de url muy comúnmente será http://localhost:8080/todo/api/todos/ , la cual está compuesta por:
localhost: dominio que redirige a nuestra IP local.
Puerto 8080: en el cual se ejecuta nuestro servidor de aplicaciones por defecto.
todo: el nombre de nuestra aplicación.
api: parte de la ruta que definimos para el Servlet MVC de Spring en el archivo web.xml, en las lineas 18-21.
todos: parte de la ruta que definimos en el RestController con la anotación
@RequestMapping("todos")
.
Seleccionaremos el método Post ya que fue definido en el método saveTodo del RestController (@RequestMapping(method = RequestMethod.POST)
).
Después en Body creamos un JSON con la siguiente estructura {"name": "test"}
y damos click en SEND.
Deberíamos ver algo como la siguiente captura de pantalla.
Y en la consola de Eclipse debería registrarnos algo parecido a esto.
Con esta útil extensión podemos probar los métodos que estamos haciendo, para resumir el articulo omitiré las siguientes pruebas y me enfocare en la construcción de los métodos.
El método para buscar todos los Todos en nuestra aplicación se llamara getAllTodos, regresara una lista de Todos , también usara la anotación @RequestMapping, pero ahora utilizaremos el RequestMethod GET y regresara la ejecución del método findAll del TodoDao.
Crearemos un método para buscar Todos por id, este método se llamara getTodo, el cual tendrá la anotación @RequestMapping con el valor del RequestMethod igual a GET y una nueva propiedad llamada value con el siguiente String value = "/{id}"
separado por coma, recibirá como parámetro un entero llamado id con la anotación @PathVariable con el String "id"
y regresara la ejecución del método findById del TodoDao al cual le pasamos el entero id.
Para actualizar crearemos un método llamado updateTodo que estará anotado con @RequestMapping y el tipo de RequestMethod a usar será el PUT, el método recibe un Todo anotado con @RequestBody y regresa un Todo que se obtiene del método del TodoDao llamado update al que le pasaremos el Todo recibido.
Por ultimo nos queda el método para eliminar Todos de nuestra aplicación, deleteTodo, que tendrá la anotación @RequestMapping con la propiedad value de la siguiente forma value="/{id}"
y el tipo de RequestMethod a usar sera el DELETE, este método recibe como parámetro un entero primitivo llamado id con la anotación @PathVariable pasando le un String "id" como argumento así @PathVariable("id") int id
, regresara un Todo el cual obtendremos de la ejecución del método deleteById del TodoDao, al que le pasamos el id recibido como parámetro.
Es necesario aclarar que son y para que sirven las anotaciónes con las que estamos trabajando para tener un conocimiento mas amplio de lo que sucede en Spring:
@RestController: Una anotación de conveniencia que está a su vez anota con @Controller y @ResponseBody, es decir encapsula las anotaciones @Controller y @ResponseBody en una sola.
@Controller: Indica que una clase con esta anotación es un "controlador" (por ejemplo, un controlador web), mas información de los componentes de Spring aquí.
@ResponseBody: Anotación que indica que el valor de retorno del método debe estar en el cuerpo de una respuesta web.
@Autowired: Anotación para inyectar dependencias, existen algunas alternativas que podemos ver aquí.
@PathVariable: Anotación que indica que un parámetro del método debe estar dado por una variable de plantilla en la URL.
@RequestMapping: Sirve para mapear una determinada petición de un cliente a un controlador o a un método especifico ya sea por un String o por alguno de los diferentes métodos de HTTP que se encuentran en la clase ENUM RequestMethod.
@RequestBody: indica que un parámetro del método debe estar obligatoria mente en el cuerpo de la petición Web. El cuerpo de la petición se pasa a través de un HttpMessageConverter para resolver el argumento del método dependiendo del tipo de contenido de la petición.
Al finalizar este articulo ya tendiéramos nuestra API REST funcionando y tenemos conceptos básicos de como es el marco de trabajo con Spring, así como que son y para que sirven las anotaciones mas comunes en este tipo de proyectos.
Podemos decir que de cara a los desarrolladores que consumirán nuestra API, es sencilla, para mantenerla así es recomendable seguir esta guía de estilo para diseñar y desarrollar una API.
Algo que puede resultar confuso es por que cada vez que se reinicia el server los datos se pierden, bueno esto es debido a nuestra base de datos (H2) que mas que nada es de prueba, en próximos artículos detallare como cambiarla.
Un dato curioso, es que segun Stackoverflow podriamos utilizar PATCH en lugar de PUT, aun resulta confuso decidir que utilizar pero siguiendo las recomendaciones anteriores PUT esta bien.
El código del proyecto hasta este punto pueden descargarlo aquí.