Introducció a les Unions en GraphQL

Les unions en GraphQL permeten definir un tipus que pot ser un de diversos tipus diferents. Això és útil quan es vol retornar diferents tipus d'objectes en una sola consulta. Les unions són similars a les interfícies, però a diferència d'aquestes, no requereixen que els tipus que les implementen comparteixin cap camp comú.

Definició d'Unions

Sintaxi bàsica

Per definir una union en GraphQL, utilitzem la paraula clau union seguida del nom de la union i els tipus que la componen.

union SearchResult = User | Post | Comment

En aquest exemple, SearchResult és una union que pot ser un User, un Post o un Comment.

Exemple pràctic

Suposem que tenim els següents tipus definits en el nostre esquema:

type User {
  id: ID!
  name: String!
}

type Post {
  id: ID!
  title: String!
  content: String!
}

type Comment {
  id: ID!
  text: String!
}

Podem definir una union SearchResult que pot ser qualsevol d'aquests tres tipus:

union SearchResult = User | Post | Comment

Utilització d'Unions en Consultes

Quan utilitzem unions en les nostres consultes, hem de fer servir fragments per especificar com volem que es resolguin els diferents tipus.

Exemple de consulta

query {
  search(term: "GraphQL") {
    ... on User {
      id
      name
    }
    ... on Post {
      id
      title
      content
    }
    ... on Comment {
      id
      text
    }
  }
}

En aquesta consulta, search retorna un SearchResult, que pot ser un User, un Post o un Comment. Utilitzem fragments per especificar quins camps volem per a cada tipus.

Implementació de Resolvers per a Unions

Quan implementem resolvers per a unions, hem de proporcionar una funció de resolució per a la union que determini quin tipus específic s'ha de retornar.

Exemple de resolver

const resolvers = {
  Query: {
    search: (parent, args, context, info) => {
      // Lògica per buscar usuaris, posts i comentaris
      // Retorna una llista de resultats que poden ser de diferents tipus
    },
  },
  SearchResult: {
    __resolveType(obj, context, info) {
      if (obj.name) {
        return 'User';
      }
      if (obj.title) {
        return 'Post';
      }
      if (obj.text) {
        return 'Comment';
      }
      return null;
    },
  },
};

En aquest exemple, la funció __resolveType determina el tipus de cada objecte retornat per la consulta search.

Exercici Pràctic

Enunciat

  1. Defineix una union Media que pugui ser un Photo o un Video.
  2. Defineix els tipus Photo i Video amb els següents camps:
    • Photo: id, url, description
    • Video: id, url, duration
  3. Escriu una consulta media que retorni una llista de Media.
  4. Implementa els resolvers necessaris per a la consulta media i la union Media.

Solució

Esquema

type Photo {
  id: ID!
  url: String!
  description: String
}

type Video {
  id: ID!
  url: String!
  duration: Int
}

union Media = Photo | Video

type Query {
  media: [Media]
}

Resolvers

const resolvers = {
  Query: {
    media: () => {
      return [
        { id: '1', url: 'http://example.com/photo1.jpg', description: 'A beautiful sunrise', __typename: 'Photo' },
        { id: '2', url: 'http://example.com/video1.mp4', duration: 120, __typename: 'Video' },
      ];
    },
  },
  Media: {
    __resolveType(obj, context, info) {
      if (obj.description) {
        return 'Photo';
      }
      if (obj.duration) {
        return 'Video';
      }
      return null;
    },
  },
};

Consulta

query {
  media {
    ... on Photo {
      id
      url
      description
    }
    ... on Video {
      id
      url
      duration
    }
  }
}

Conclusió

Les unions en GraphQL són una eina poderosa per retornar diferents tipus d'objectes en una sola consulta. Utilitzant fragments i resolvers adequats, podem gestionar fàcilment aquestes estructures complexes i proporcionar respostes flexibles i riques en dades.

© Copyright 2024. Tots els drets reservats