CodeGym /Cursos /Módulo 5. Spring /Práctica: creación de un controlador REST en Spring MVC

Práctica: creación de un controlador REST en Spring MVC

Módulo 5. Spring
Nivel 7 , Lección 5
Disponible

En las lecciones anteriores vimos los fundamentos de Spring MVC: la arquitectura, las anotaciones clave y los principios básicos de enrutamiento. Ahora es momento de aplicar ese conocimiento en la práctica y crear una API REST completa.

Vamos a diseñar un controlador para gestionar libros en una biblioteca. Nuestra API podrá obtener la lista de libros, buscar un libro por ID, añadir libros nuevos, actualizar su información y eliminarlos de la base. En el proceso crearemos todas las operaciones CRUD necesarias, aprenderemos a manejar correctamente los métodos HTTP (GET, POST, PUT, DELETE), configuraremos la devolución de datos en formato JSON y añadiremos pruebas básicas.

La API REST es la base del desarrollo web moderno. Ya sea que desarrolles una aplicación web, una app móvil o una arquitectura de microservicios, tendrás que crear y mantener API-endpoints. ¡Aprendamos a hacerlo bien!


1. Preparación del proyecto

Dependencias. Para empezar, asegúrate de que tu proyecto Spring Boot está configurado correctamente. Incluye en el proyecto las dependencias necesarias en el archivo pom.xml:


<dependencies>
  <!-- Spring Web para trabajar con MVC -->
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
  </dependency>
  <!-- Dependencia para trabajar con JSON -->
  <dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
  </dependency>
</dependencies>

Bueno, ahora manos a la obra y creemos el controlador.


2. Descripción de la entidad Book

Antes de implementar el controlador necesitamos la entidad que va a manejar. Creamos una clase sencilla para la entidad Book.


package com.example.demo.model;

public class Book {

    private Long id;
    private String title;
    private String author;

    // Constructores
    public Book() {}

    public Book(Long id, String title, String author) {
        this.id = id;
        this.title = title;
        this.author = author;
    }

    // Getters y setters
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }
}

3. Creación del REST-controller

Ahora estamos listos para crear nuestro controlador. Manejará las solicitudes HTTP para gestionar libros. Usaremos la anotación @RestController para indicar a Spring que esta clase atiende solicitudes REST.


package com.example.demo.controller;

import com.example.demo.model.Book;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;

@RestController
@RequestMapping("/books")
public class BookController {

    private final List<Book> books = new ArrayList<>();

    // Inicialización de datos
    public BookController() {
        books.add(new Book(1L, "Clean Code", "Robert C. Martin"));
        books.add(new Book(2L, "Effective Java", "Joshua Bloch"));
    }

    // Obtener todos los libros
    @GetMapping
    public List<Book> getAllBooks() {
        return books;
    }

    // Obtener libro por ID
    @GetMapping("/{id}")
    public Book getBookById(@PathVariable Long id) {
        return books.stream()
                .filter(book -> book.getId().equals(id))
                .findFirst()
                .orElseThrow(() -> new RuntimeException("Book not found"));
    }

    // Crear nuevo libro
    @PostMapping
    public Book createBook(@RequestBody Book book) {
        books.add(book);
        return book;
    }

    // Actualizar libro
    @PutMapping("/{id}")
    public Book updateBook(@PathVariable Long id, @RequestBody Book updatedBook) {
        Book book = getBookById(id);
        book.setTitle(updatedBook.getTitle());
        book.setAuthor(updatedBook.getAuthor());
        return book;
    }

    // Eliminar libro
    @DeleteMapping("/{id}")
    public void deleteBook(@PathVariable Long id) {
        Book book = getBookById(id);
        books.remove(book);
    }
}

4. Análisis del código del controlador

Principales métodos del controlador

  • GET /books Devuelve la lista de todos los libros. Muy sencillo, usa la variable books para devolver la lista.
  • GET /books/{id} Busca un libro por ID. Si no se encuentra, se lanza una excepción (se puede mejorar el manejo de errores más adelante).
  • POST /books Crea un libro nuevo. Pasamos un objeto Book en el cuerpo de la petición (anotación @RequestBody).
  • PUT /books/{id} Actualiza un libro existente por ID. Primero buscamos el libro por ID y luego actualizamos sus datos.
  • DELETE /books/{id} Elimina un libro por ID. Primero buscamos el libro y luego lo quitamos de la lista.

Parámetros de las anotaciones

  • @RequestMapping("/books"): ruta base para todas las solicitudes.
  • @GetMapping, @PostMapping, @PutMapping, @DeleteMapping: manejan los distintos métodos HTTP.
  • @PathVariable extrae parámetros desde la ruta de la petición.
  • @RequestBody lee el cuerpo de la petición y lo convierte en un objeto Java.

5. Pruebas del controlador

Puedes comprobar la API usando herramientas como Postman o curl. Ejemplos de peticiones:

GET todos los libros


GET http://localhost:8080/books

GET libro por ID


GET http://localhost:8080/books

POST nuevo libro


POST http://localhost:8080/books
Content-Type: application/json

{
    "id": 3,
    "title": "The Pragmatic Programmer",
    "author": "Andrew Hunt"
}

DELETE eliminar libro


DELETE http://localhost:8080/books/1

6. Errores típicos y cómo solucionarlos

  1. Error 404 Not Found en GET /books/{id} Esto ocurre si el libro buscado no está en la lista. Asegúrate de que la variable books esté inicializada correctamente.
  2. Error en la serialización JSON Comprueba que todos los campos de los objetos tengan getters/setters; si no, Jackson no podrá convertir el objeto a JSON.
  3. Error 415 Unsupported Media Type en peticiones POST o PUT Asegúrate de que la cabecera de la petición incluya Content-Type: application/json.

¡Ahora tenemos un controlador REST completamente funcional! En la siguiente clase conoceremos el motor de plantillas Thymeleaf, para aprender a crear páginas HTML atractivas para nuestras aplicaciones web.

Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION