Introducción
En GraphQL, las uniones (unions) son una forma poderosa de definir un tipo que puede ser uno de varios tipos diferentes. Esto es útil cuando tienes un campo que puede devolver diferentes tipos de objetos y quieres que tu esquema sea flexible y expresivo.
Conceptos Clave
- Definición de Uniones: Una unión es un tipo especial en GraphQL que permite que un campo pueda retornar uno de varios tipos posibles.
- Uso de Uniones: Las uniones se utilizan cuando un campo puede devolver diferentes tipos de objetos que no comparten una interfaz común.
- Resolución de Uniones: Los resolvers deben ser capaces de determinar qué tipo de objeto se está devolviendo para una unión.
Definición de Uniones
Para definir una unión en GraphQL, utilizamos la palabra clave union
seguida del nombre de la unión y los tipos que puede incluir. Aquí hay un ejemplo básico:
En este ejemplo, SearchResult
es una unión que puede ser un User
, un Post
o un Comment
.
Ejemplo Práctico
Supongamos que estamos construyendo una API para una red social y queremos implementar una búsqueda que pueda devolver usuarios, publicaciones o comentarios. Primero, definimos los tipos:
type User { id: ID! name: String! } type Post { id: ID! title: String! content: String! } type Comment { id: ID! text: String! author: User! }
Luego, definimos la unión:
Finalmente, definimos una consulta que utiliza esta unión:
Resolver para Uniones
Cuando se utiliza una unión, el resolver debe ser capaz de determinar el tipo de objeto que se está devolviendo. Aquí hay un ejemplo de cómo se puede implementar esto en JavaScript utilizando Apollo Server:
const { ApolloServer, gql } = require('apollo-server'); // Definición del esquema const typeDefs = gql` type User { id: ID! name: String! } type Post { id: ID! title: String! content: String! } type Comment { id: ID! text: String! author: User! } union SearchResult = User | Post | Comment type Query { search(term: String!): [SearchResult!]! } `; // Datos de ejemplo const users = [ { id: '1', name: 'Alice' }, { id: '2', name: 'Bob' }, ]; const posts = [ { id: '1', title: 'GraphQL Rocks', content: 'GraphQL is awesome!' }, { id: '2', title: 'Apollo Server', content: 'Apollo Server is great!' }, ]; const comments = [ { id: '1', text: 'Great post!', author: users[0] }, { id: '2', text: 'Very informative.', author: users[1] }, ]; // Resolver const resolvers = { Query: { search: (parent, args) => { const term = args.term.toLowerCase(); const userResults = users.filter(user => user.name.toLowerCase().includes(term)); const postResults = posts.filter(post => post.title.toLowerCase().includes(term)); const commentResults = comments.filter(comment => comment.text.toLowerCase().includes(term)); return [...userResults, ...postResults, ...commentResults]; }, }, SearchResult: { __resolveType(obj) { if (obj.name) { return 'User'; } if (obj.title) { return 'Post'; } if (obj.text) { return 'Comment'; } return null; }, }, }; // Creación del servidor const server = new ApolloServer({ typeDefs, resolvers }); // Inicio del servidor server.listen().then(({ url }) => { console.log(`🚀 Server ready at ${url}`); });
Ejercicio Práctico
Ejercicio
- Define una unión llamada
Content
que pueda ser unArticle
o unVideo
. - Crea los tipos
Article
yVideo
con los siguientes campos:Article
:id
,title
,body
Video
:id
,title
,url
- Define una consulta llamada
getContent
que devuelva una lista deContent
. - Implementa los resolvers necesarios para manejar la unión
Content
.
Solución
# Definición del esquema type Article { id: ID! title: String! body: String! } type Video { id: ID! title: String! url: String! } union Content = Article | Video type Query { getContent: [Content!]! }
// Datos de ejemplo const articles = [ { id: '1', title: 'GraphQL Tutorial', body: 'Learn GraphQL step by step.' }, { id: '2', title: 'Advanced GraphQL', body: 'Deep dive into GraphQL.' }, ]; const videos = [ { id: '1', title: 'GraphQL Basics', url: 'http://example.com/graphql-basics' }, { id: '2', title: 'GraphQL Advanced', url: 'http://example.com/graphql-advanced' }, ]; // Resolver const resolvers = { Query: { getContent: () => { return [...articles, ...videos]; }, }, Content: { __resolveType(obj) { if (obj.body) { return 'Article'; } if (obj.url) { return 'Video'; } return null; }, }, }; // Creación del servidor const server = new ApolloServer({ typeDefs, resolvers }); // Inicio del servidor server.listen().then(({ url }) => { console.log(`🚀 Server ready at ${url}`); });
Conclusión
Las uniones en GraphQL son una herramienta poderosa para manejar tipos de datos flexibles y variados. Permiten que un campo pueda devolver diferentes tipos de objetos, lo que hace que tu API sea más expresiva y adaptable a diferentes necesidades. Asegúrate de definir claramente los tipos que pueden formar parte de una unión y de implementar resolvers que puedan determinar correctamente el tipo de objeto que se está devolviendo.
Curso de GraphQL
Módulo 1: Introducción a GraphQL
- ¿Qué es GraphQL?
- GraphQL vs REST
- Configuración de un Servidor GraphQL
- Conceptos Básicos del Esquema de GraphQL
Módulo 2: Conceptos Fundamentales
Módulo 3: Diseño Avanzado de Esquemas
Módulo 4: Trabajando con Datos
Módulo 5: Rendimiento y Seguridad
Módulo 6: Herramientas y Ecosistema
Módulo 7: Pruebas y Despliegue
- Pruebas Unitarias de Resolvers
- Pruebas de Integración
- Integración Continua
- Despliegue de Servidores GraphQL