Integración sin esfuerzo de APIs RESTful y GraphQL con Spring Boot para servicios flexibles
Introducción
En el ecosistema empresarial moderno, las APIs son una parte fundamental de la arquitectura de software. Las arquitecturas flexibles requieren que integremos múltiples tipos de APIs, como RESTful y GraphQL, para satisfacer diversas necesidades. Este artículo abordará cómo implementar y combinar ambos tipos de APIs en un solo proyecto de Spring Boot, permitiendo crear servicios más versátiles.
Prerrequisitos y configuración
Asegúrate de tener el siguiente entorno configurado:
- Java 11 o superior
- Spring Boot 3.x
- Dependencias de Web, JPA y GraphQL
Configura tu proyecto pom.xml
o build.gradle
con las siguientes dependencias:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.graphql-java-kickstart</groupId>
<artifactId>graphql-spring-boot-starter</artifactId>
</dependency>
Implementación paso a paso
Creación de un API RESTful
Primero, implementemos un simple controlador REST para gestionar entidades Product
.
@RestController
@RequestMapping("/api/products")
public class ProductController {
@Autowired
private ProductService productService;
@GetMapping
public List<Product> getAllProducts() {
return productService.findAll();
}
@PostMapping
public Product createProduct(@RequestBody Product product) {
return productService.save(product);
}
}
Implementación de GraphQL
A continuación, definimos un endpoint GraphQL para la misma entidad Product
.
@Component
public class ProductGraphQLResolver implements GraphQLQueryResolver, GraphQLMutationResolver {
@Autowired
private ProductService productService;
public List<Product> allProducts() {
return productService.findAll();
}
public Product createProduct(ProductInput input) {
return productService.save(input.toProduct());
}
}
Definimos el esquema GraphQL en un archivo schema.graphqls
:
type Query {
allProducts: [Product]
}
type Mutation {
createProduct(product: ProductInput): Product
}
type Product {
id: ID
name: String
price: Float
}
input ProductInput {
name: String
price: Float
}
Mejores prácticas y patrones
- Utilizar capas de servicio para la lógica de negocio para desacoplar controladores de la lógica empresarial.
- Implementar DTO y Mappers para transformar entidades a respuestas API y viceversa.
Tests y validación
Implementa pruebas unitarias y de integración utilizando el framework JUnit y Spring Boot Test para asegurar la funcionalidad de ambos tipos de APIs.
@SpringBootTest
public class ProductControllerTest {
@Autowired
private MockMvc mockMvc;
@Test
public void getAllProducts_ReturnsProductList() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.get("/api/products"))
.andExpect(status().isOk())
.andExpect(jsonPath("$", hasSize(greaterThan(0))));
}
}
Consideraciones de rendimiento y seguridad
- Utiliza caché en consultas GraphQL con
DataLoader
para optimizar consultas de datos relaciones. - Implementa seguridad con
Spring Security
para proteger tus endpoints con autenticación y autorización.
Conclusiones y siguientes pasos
Esta configuración inicial proporciona una base robusta para construir aplicaciones resilientes y flexibles. Considera explorar Spring Boot Actuator y GraphQL subscription para funcionalidades avanzadas.
Documentación oficial: Spring Boot, GraphQL Spring Boot.