Cuando un servidor expone una API, los parámetros y los datos de las peticiones juegan un papel clave en la gestión de recursos. Hoy veremos:
- Manejo de Query Parameters: filtros y ordenación.
- Trabajo con Path Variables: segmentos dinámicos del URI.
- Cómo manejar errores relacionados con los parámetros.
Y, por supuesto, ¡escribiremos código! Porque la teoría sin práctica es como un método sin implementación.
¿Qué son los Query Parameters?
Empecemos con los Query Parameters. Son los parámetros que el cliente pasa en la cadena de consulta después del símbolo ?. Se usan para filtrar, ordenar, buscar datos y para otras aclaraciones de la petición.
Ejemplo de URL con Query Parameters:
https://api.myapp.com/products?category=electronics&sort=price&order=asc
- category=electronics: indica un filtro por la categoría "electrónica".
- sort=price: indica que ordenamos por el campo "price".
- order=asc: aclara que la ordenación es ascendente.
La anotación @RequestParam
Para manejar Query Parameters en Spring se usa la anotación @RequestParam. Veamos un ejemplo de código:
@RestController
@RequestMapping("/products")
public class ProductController {
@GetMapping
public List<Product> getProducts(
@RequestParam(required = false) String category,
@RequestParam(defaultValue = "name") String sort,
@RequestParam(defaultValue = "asc") String order
) {
// Lógica de filtrado y ordenación
return productService.getProducts(category, sort, order);
}
}
@RequestParam(required = false): el parámetro no es obligatorio. Si el cliente no pasacategory, seránull.defaultValue: establece un valor por defecto si el parámetro no está en la petición.
Cuando la petición va a /products?category=clothing, en el método getProducts la variable category tendrá el valor "clothing", y sort y order tomarán los valores por defecto.
¿Qué son los Path Variables?
Los Path Variables (variables de ruta) son partes del URI que contienen valores dinámicos.
Imagina que tenemos una REST API para gestionar productos y necesitamos obtener un producto por su ID. Ejemplo de URI:
https://api.myapp.com/products/42
Aquí 42 es el identificador del producto, y queremos extraerlo de la ruta. Para eso usamos la anotación @PathVariable.
La anotación @PathVariable
Spring permite "rascar" esos valores del URI así:
@RestController
@RequestMapping("/products")
public class ProductController {
@GetMapping("/{id}")
public Product getProductById(@PathVariable Long id) {
// Lógica para obtener el producto por su ID
return productService.getProductById(id);
}
}
Cuando el cliente hace GET /products/42, la variable id recibirá el valor 42.
Combinando @RequestParam y @PathVariable
Ahora, como dicen los programadores, subimos un nivel. ¡Podemos combinarlos! Por ejemplo, podemos hacer lo siguiente:
- El URI contiene un valor dinámico (
id) para identificar el recurso. - Los Query Parameters se usan para configuraciones adicionales.
Ejemplo: obtener los pedidos de un usuario con filtro
@RestController
@RequestMapping("/users")
public class UserController {
@GetMapping("/{userId}/orders")
public List<Order> getUserOrders(
@PathVariable Long userId,
@RequestParam(required = false) String status,
@RequestParam(defaultValue = "date") String sort
) {
// Lógica de filtrado de los pedidos del usuario
return orderService.getUserOrders(userId, status, sort);
}
}
Petición:
GET /users/101/orders?status=completed&sort=price
En este ejemplo:
userIdtendrá el valor101.statustendrá el valor"completed".sorttendrá el valor"price".
Validando los parámetros de la petición
No siempre los clientes nos enviarán datos correctos. Por ejemplo, ¿qué hacer si en la petición el ID del usuario viene como abc, que claramente no es válido?
Manejo de errores
Spring devolverá automáticamente un error si @PathVariable o @RequestParam no coincide con el tipo esperado. Por ejemplo:
@GetMapping("/{id}")
public Product getProductById(@PathVariable Long id) {
return productService.getProductById(id);
}
La petición GET /products/abc provocará:
HTTP 400 Bad Request
Para hacer el manejo de errores más elegante, puedes usar la anotación @ExceptionHandler:
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(MethodArgumentTypeMismatchException.class)
public ResponseEntity<String> handleTypeMismatch(MethodArgumentTypeMismatchException ex) {
return ResponseEntity
.badRequest()
.body("Invalid parameter: " + ex.getName());
}
}
Ahora el error será más amistoso para el cliente:
HTTP 400 Bad Request
Body: Invalid parameter: id
Práctica: Ejemplo de REST API para trabajar con libros
Vamos a crear un REST API para manejar libros. El API permitirá:
- Obtener un libro por ID.
- Buscar libros por género con ordenación.
Entidad Book
@Entity
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String title;
private String genre;
private double price;
// Getters y setters
}
Repositorio BookRepository
@Repository
public interface BookRepository extends JpaRepository<Book, Long> {
List<Book> findByGenre(String genre, Sort sort);
}
Servicio BookService
@Service
public class BookService {
@Autowired
private BookRepository bookRepository;
public Book getBookById(Long id) {
return bookRepository.findById(id)
.orElseThrow(() -> new RuntimeException("Book not found!"));
}
public List<Book> getBooksByGenre(String genre, String sortField) {
Sort sort = Sort.by(Sort.Direction.ASC, sortField);
return bookRepository.findByGenre(genre, sort);
}
}
Controlador BookController
@RestController
@RequestMapping("/books")
public class BookController {
@Autowired
private BookService bookService;
@GetMapping("/{id}")
public Book getBookById(@PathVariable Long id) {
return bookService.getBookById(id);
}
@GetMapping
public List<Book> getBooksByGenre(
@RequestParam(required = false) String genre,
@RequestParam(defaultValue = "title") String sort
) {
return bookService.getBooksByGenre(genre, sort);
}
}
Ahora:
GET /books/1devolverá el libro con ID 1.GET /books?genre=fantasy&sort=pricedevolverá todos los libros del género "fantasy", ordenados por el campo "price".
Errores típicos y cómo solucionarlos
@PathVariablefaltante en el URI. Asegúrate de que la variable de ruta esté indicada en la ruta (por ejemplo,/{id}).- Tipo de dato incorrecto del parámetro. Si
idespera unLongy el cliente pasa una cadena, habrá un error 400. - Falta de Query Parameters obligatorios. Asegúrate de usar
required = falsesi el parámetro no es obligatorio.
En este punto ya dominas el trabajo con Query Parameters y Path Variables. Ahora tus REST APIs serán más funcionales y flexibles. Sigue con el curso y no olvides testear tus APIs.
GO TO FULL VERSION