CRUD — es un acrónimo de cuatro operaciones: Create (Creación), Read (Lectura), Update (Actualización) y Delete (Eliminación). En el contexto de REST API, CRUD corresponde al siguiente conjunto de métodos HTTP:
| Operación (CRUD) | Método HTTP | Propósito |
|---|---|---|
| Create | POST | Creación de un nuevo recurso |
| Read | GET | Obtención de los datos del recurso |
| Update | PUT/PATCH | Modificación de un recurso existente |
| Delete | DELETE | Eliminación del recurso |
Crear un CRUD API es la base para interactuar con cualquier recurso en una aplicación web. Vamos a construir nuestro primer REST API completo para gestionar, por ejemplo, la entidad Product.
Desarrollo de entidades y repositorios
Creación de la entidad Product
Para trabajar con datos en la base en Spring usamos anotaciones de JPA (Java Persistence API). Crearemos la clase Product, que representará nuestra entidad.
package com.example.demo.model;
import jakarta.persistence.*;
// La anotación @Entity convierte la clase en una entidad JPA
@Entity
@Table(name = "products") // Nombre de la tabla en la base de datos
public class Product {
@Id // Clave primaria
@GeneratedValue(strategy = GenerationType.IDENTITY) // Auto-increment
private Long id;
@Column(nullable = false) // El campo no debe ser null
private String name;
private String description;
@Column(nullable = false)
private Double price;
// Getters y setters (para trabajar con los campos vía Hibernate)
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
}
Creación del repositorio
Para interactuar con la base de datos usamos las interfaces de Spring Data JPA, como JpaRepository. Crearemos un repositorio para la entidad Product.
package com.example.demo.repository;
import com.example.demo.model.Product;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
// Repositorio para trabajar con Product
@Repository
public interface ProductRepository extends JpaRepository<Product, Long> {
}
Con este repositorio haremos todas las operaciones básicas con la base de datos: guardar, obtener, eliminar y actualizar registros.
Implementación de controladores CRUD
Ahora vamos a crear un controlador REST que hará las operaciones CRUD.
Creación del controlador CRUD
package com.example.demo.controller;
import com.example.demo.model.Product;
import com.example.demo.repository.ProductRepository;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
// La anotación @RestController indica que es un controlador RESTful
@RestController
@RequestMapping("/api/products") // Ruta base para todas las peticiones
public class ProductController {
private final ProductRepository productRepository;
// Inyección de dependencia vía constructor
public ProductController(ProductRepository productRepository) {
this.productRepository = productRepository;
}
// Obtener todos los productos (Read - GET)
@GetMapping
public List<Product> getAllProducts() {
return productRepository.findAll();
}
// Obtener producto por ID (Read - GET)
@GetMapping("/{id}")
public ResponseEntity<Product> getProductById(@PathVariable Long id) {
return productRepository.findById(id)
.map(product -> ResponseEntity.ok(product))
.orElse(ResponseEntity.notFound().build());
}
// Crear un nuevo producto (Create - POST)
@PostMapping
public ResponseEntity<Product> createProduct(@RequestBody Product product) {
Product savedProduct = productRepository.save(product);
return ResponseEntity.status(HttpStatus.CREATED).body(savedProduct);
}
// Actualizar un producto existente (Update - PUT)
@PutMapping("/{id}")
public ResponseEntity<Product> updateProduct(@PathVariable Long id, @RequestBody Product productDetails) {
return productRepository.findById(id)
.map(existingProduct -> {
existingProduct.setName(productDetails.getName());
existingProduct.setDescription(productDetails.getDescription());
existingProduct.setPrice(productDetails.getPrice());
Product updatedProduct = productRepository.save(existingProduct);
return ResponseEntity.ok(updatedProduct);
})
.orElse(ResponseEntity.notFound().build());
}
// Eliminar producto (Delete - DELETE)
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteProduct(@PathVariable Long id) {
return productRepository.findById(id)
.map(product -> {
productRepository.delete(product);
return ResponseEntity.noContent().build();
})
.orElse(ResponseEntity.notFound().build());
}
}
El REST API para operaciones CRUD está listo. Añadamos un poco más de práctica.
Ejercicio práctico: comprobar el funcionamiento del API
Arranca la aplicación y comprueba que funciona. Aquí tienes algunos ejemplos de peticiones que puedes hacer con Postman o curl.
Creación de producto (POST)
Petición:
POST /api/products
Content-Type: application/json
{
"name": "Laptop",
"description": "A powerful gaming laptop",
"price": 1500.0
}
Respuesta:
{
"id": 1,
"name": "Laptop",
"description": "A powerful gaming laptop",
"price": 1500.0
}
Obtener todos los productos (GET)
Petición:
GET /api/products
Respuesta:
[
{
"id": 1,
"name": "Laptop",
"description": "A powerful gaming laptop",
"price": 1500.0
}
]
Actualización de producto (PUT)
Petición:
PUT /api/products/1
Content-Type: application/json
{
"name": "Laptop Pro",
"description": "An even more powerful gaming laptop",
"price": 2000.0
}
Respuesta:
{
"id": 1,
"name": "Laptop Pro",
"description": "An even more powerful gaming laptop",
"price": 2000.0
}
Eliminación de producto (DELETE)
Petición:
DELETE /api/products/1
Respuesta:
204 No Content
Errores típicos y su solución
Error: Resource Not Found (404)
Si pasas un ID incorrecto del recurso, la aplicación devuelve 404 Not Found. Esto es un comportamiento correcto.
Consejo: siempre comprueba el ID antes de la petición para evitar procesamientos innecesarios.
Error: Invalid JSON Body
Si el cuerpo de la petición no coincide con el formato esperado, recibirás 400 Bad Request.
Consejo: asegúrate de que tu JSON esté bien formado y usa las herramientas integradas de Postman o tu IDE para validarlo.
Cómo se usa esto en proyectos reales
Crear REST API es la base para la mayoría de aplicaciones web modernas. Escenarios potenciales:
- Gestión del catálogo de productos para una tienda online.
- Integración con dispositivos móviles para entregar datos.
- Interacción entre microservicios mediante REST API.
Tus CRUD API son el bloque básico de cualquier proyecto backend. Así que pule esta habilidad hasta que la domines, porque de ella depende el éxito de tu aplicación.
GO TO FULL VERSION