Aprende a conectar un backend Spring Boot a una API externa usando RestTemplate o WebClient, y gestionar autenticación con Bearer Token.
Conectar tu aplicación backend hecha en Spring Boot a una API externa es una habilidad fundamental si quieres consumir datos de servicios de terceros como OpenWeather, APIs de monedas, servicios internos, etc.
Crear un proyecto Spring Boot
Usar RestTemplate para hacer peticiones HTTP
Leer datos desde una API externa pública
Mostrar esos datos a través de tu propia API
Usa Spring Initializr y genera un proyecto con las siguientes dependencias:
Configuraciones:
com.ejemplo
conexionapi
Haz clic en “Generate” y descomprime el archivo ZIP. Luego ábrelo en tu editor favorito (por ejemplo, IntelliJ o VS Code).
Vamos a usar una API llamada JSONPlaceholder, que simula una API real para practicar.
Por ejemplo, si haces una petición a:
https://jsonplaceholder.typicode.com/posts
Obtendrás algo como esto:
{
"userId": 1,
"id": 1,
"title": "titulo del post",
"body": "contenido del post"
}
Eso significa que la API te devuelve una lista de objetos Post, que tienen los campos userId, id, title y body.
Creamos una clase Java llamada Post.java para representar cada uno de esos objetos.
📁 Ubicación: src/main/java/com/ejemplo/conexionapi/model/Post.java
package com.ejemplo.conexionapi.model;
// Esta clase representa la estructura del objeto que recibimos de la API externa
public class Post {
private int userId;
private int id;
private String title;
private String body;
// Métodos getter y setter para que Spring pueda acceder a los campos
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
}
👉 Esta clase le dice a Spring cómo debe interpretar los datos JSON que recibimos desde la API.
Para hacer llamadas HTTP desde Java, usaremos una clase que Spring Boot nos da: RestTemplate.
📁 src/main/java/com/ejemplo/conexionapi/config/RestTemplateConfig.java
RestTemplateConfig.java
package com.ejemplo.conexionapi.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
// Esta clase dice a Spring cómo crear un RestTemplate y que lo tenga disponible para inyectarlo en otros lugares
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
PostService.java
package com.ejemplo.conexionapi.service;
import com.ejemplo.conexionapi.model.Post;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import java.util.Arrays;
import java.util.List;
// Esta clase contiene la lógica para hacer la llamada a la API externa
@Service
public class PostService {
private static final String API_URL = "https://jsonplaceholder.typicode.com/posts";
@Autowired
private RestTemplate restTemplate;
public List<Post> obtenerPosts() {
// Hacemos una petición GET a la API externa y convertimos el JSON recibido en un array de objetos Post
Post[] posts = restTemplate.getForObject(API_URL, Post[].class);
// Convertimos el array en una lista para trabajar más cómodamente
return Arrays.asList(posts);
}
}
Vamos a crear una ruta en nuestro propio backend para que podamos acceder a esos posts.
📁 src/main/java/com/ejemplo/conexionapi/controller/PostController.java
PostController.java
package com.ejemplo.conexionapi.controller;
import com.ejemplo.conexionapi.model.Post;
import com.ejemplo.conexionapi.service.PostService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
// Este controlador escucha peticiones HTTP en /api/posts
@RestController
@RequestMapping("/api/posts")
public class PostController {
@Autowired
private PostService postService;
@GetMapping
public List<Post> getPosts() {
// Cuando alguien visita /api/posts, respondemos con la lista de posts obtenida desde la API externa
return postService.obtenerPosts();
}
}
Ejecuta tu aplicación Spring Boot. Puedes hacer esto desde tu IDE, o con el siguiente comando si usas terminal:
./mvnw spring-boot:run
Luego abre tu navegador y entra a: http://localhost:8080/api/posts
Deberías ver un JSON con los posts traídos desde la API externa.
Hay muchas APIs en internet que no te dejan usarlas sin antes “identificarte”. Para eso, muchas usan lo que se llama un Bearer Token. En esta parte del tutorial vas a aprender:
Qué es un Bearer Token y para qué sirve
Cómo enviar ese token al hacer una llamada HTTP
Dos formas de hacerlo: usando RestTemplate y WebClient
Piensa en un Bearer Token como una tarjeta de acceso. Cuando haces una petición a una API protegida, necesitas decir: 🗣️ “¡Hola! Tengo este token que prueba que estoy autorizado”.
Esto se hace enviando un encabezado HTTP llamado Authorization, que se ve así:
Authorization: Bearer TU_TOKEN
Si quieres usar WebClient, necesitas agregar la dependencia de Spring WebFlux en tu archivo pom.xml, ya que WebClient es parte de este módulo.
Ve a tu archivo pom.xml y agrega lo siguiente:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
🧩 ¿Por qué necesitas esto?
Spring WebFlux es un módulo que incluye herramientas como WebClient para trabajar con programación reactiva (aunque también puedes usarlo de manera tradicional).
Asegúrate de tener esta dependencia además de spring-boot-starter-web, si es que usas ambos: RestTemplate para peticiones tradicionales y WebClient para las más modernas.
Supongamos que la API protegida está en esta URL:
https://api.ejemplo.com/data
Y te dieron este token:
abcdef123456
Necesitamos enviar ese token como un header cuando hagamos la petición.
Igual que antes, creamos una clase que represente los datos que devuelve esa API.
📁 Dato.java
package com.ejemplo.conexionapi.model;
public class Dato {
private String id;
private String nombre;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getNombre() {
return nombre;
}
public void setNombre(String nombre) {
this.nombre = nombre;
}
}
Vamos a crear una clase llamada DatoService que use RestTemplate para llamar a la API y enviar el token.
📁 DatoService.java
package com.ejemplo.conexionapi.service;
import com.ejemplo.conexionapi.model.Dato;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import java.util.Arrays;
import java.util.List;
@Service
public class DatoService {
private static final String API_URL = "https://api.ejemplo.com/data";
private static final String TOKEN = "abcdef123456";
@Autowired
private RestTemplate restTemplate;
public List<Dato> obtenerDatosConToken() {
HttpHeaders headers = new HttpHeaders();
headers.setBearerAuth(TOKEN); // Aquí se añade el header Authorization: Bearer ...
HttpEntity<String> entity = new HttpEntity<>(headers);
ResponseEntity<Dato[]> response = restTemplate.exchange(
API_URL,
HttpMethod.GET,
entity,
Dato[].class
);
return Arrays.asList(response.getBody());
}
}
WebClient es una alternativa más moderna que soporta programación reactiva, pero también se puede usar de forma simple.
📁 WebClientConfig.java
package com.ejemplo.conexionapi.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.function.client.WebClient;
@Configuration
public class WebClientConfig {
@Bean
public WebClient webClient(WebClient.Builder builder) {
return builder.baseUrl("https://api.ejemplo.com").build();
}
}
📁 DatoWebClientService.java
package com.ejemplo.conexionapi.service;
import com.ejemplo.conexionapi.model.Dato;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
import java.util.List;
@Service
public class DatoWebClientService {
private static final String TOKEN = "abcdef123456";
@Autowired
private WebClient webClient;
public List<Dato> obtenerDatos() {
Mono<Dato[]> response = webClient
.get()
.uri("/data")
.headers(headers -> headers.setBearerAuth(TOKEN))
.retrieve()
.bodyToMono(Dato[].class);
return List.of(response.block()); // Bloqueamos para convertirlo en forma tradicional
}
}
📁 DatoController.java
package com.ejemplo.conexionapi.controller;
import com.ejemplo.conexionapi.model.Dato;
import com.ejemplo.conexionapi.service.DatoWebClientService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api/datos")
public class DatoController {
@Autowired
private DatoWebClientService datoService;
@GetMapping
public List<Dato> getDatos() {
return datoService.obtenerDatos();
}
}
RestTemplate
para soluciones simples.WebClient
si quieres una solución más moderna o necesitas trabajar de forma reactiva.application.properties
api.token=abcdef123456
Y en tu clase:
@Value("${api.token}")
private String token;
Así puedes evitar escribir el token directamente en el código fuente.