🚀 Nuova versione beta disponibile! Feedback o problemi? Contattaci

Unioni e Interfacce in GraphQL: Guida Completa

Codegrind TeamSep 05 2024

In GraphQL, le Unioni e le Interfacce sono strumenti avanzati che permettono di creare schemi flessibili, tipizzati e modulabili. Le Unioni consentono di definire campi che possono restituire più tipi diversi, mentre le Interfacce permettono di definire una struttura comune che può essere implementata da più tipi. Questi strumenti offrono flessibilità nella progettazione delle API e permettono di rappresentare relazioni più complesse tra i dati. In questo articolo esploreremo come utilizzare le Unioni e le Interfacce in GraphQL, con esempi pratici e best practices.

Cos’è un’Unione in GraphQL?

Un’Unione in GraphQL consente di definire un campo che può restituire uno o più tipi diversi. A differenza di un’interfaccia, i tipi che fanno parte di un’Unione non devono condividere campi comuni. Le Unioni sono utili quando un campo può restituire oggetti di tipi diversi che non hanno campi in comune.

Esempio di Definizione di Unione

union SearchResult = User | Post

In questo esempio:

  • SearchResult è un’unione che può essere o un User o un Post.

Utilizzo delle Unioni nelle Query

Supponiamo di voler fare una ricerca su un sito che può restituire sia utenti (User) che post (Post).

Definizione dello Schema

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

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

union SearchResult = User | Post

type Query {
  search(keyword: String!): [SearchResult!]!
}

In questo esempio:

  • La query search può restituire una lista di oggetti che possono essere di tipo User o Post.

Query di Esempio

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

In questa query:

  • Utilizziamo la direttiva ... on per specificare come gestire i risultati di tipo User o Post.
  • Se l’oggetto restituito è un User, richiediamo id e name. Se è un Post, richiediamo id, title, e content.

Esempio di Risultato

{
  "data": {
    "search": [
      {
        "id": "1",
        "name": "Alice"
      },
      {
        "id": "101",
        "title": "GraphQL Unions and Interfaces",
        "content": "Learn how to use GraphQL Unions and Interfaces."
      }
    ]
  }
}

Cos’è un’Interfaccia in GraphQL?

Un’Interfaccia in GraphQL permette di definire un insieme di campi comuni che devono essere implementati da più tipi. A differenza delle Unioni, le Interfacce richiedono che i tipi che le implementano condividano un insieme di campi obbligatori.

Esempio di Definizione di un’Interfaccia

interface Node {
  id: ID!
}

type User implements Node {
  id: ID!
  name: String!
  email: String!
}

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

In questo esempio:

  • L’interfaccia Node definisce un campo id che deve essere implementato sia da User che da Post.
  • Sia User che Post devono quindi avere un campo id.

Utilizzo delle Interfacce nelle Query

L’interfaccia permette di scrivere query che possono restituire oggetti di diversi tipi, a patto che implementino la stessa interfaccia.

Definizione dello Schema con Interfaccia

interface Node {
  id: ID!
}

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

type Post implements Node {
  id: ID!
  title: String!
}

type Query {
  nodes: [Node!]!
}

In questo esempio:

  • La query nodes restituisce una lista di oggetti che implementano l’interfaccia Node, quindi può restituire sia User che Post.

Query di Esempio con Interfaccia

query {
  nodes {
    id
    ... on User {
      name
    }
    ... on Post {
      title
    }
  }
}

In questa query:

  • La direttiva ... on viene utilizzata per richiedere campi specifici in base al tipo di oggetto (User o Post).

Esempio di Risultato

{
  "data": {
    "nodes": [
      {
        "id": "1",
        "name": "Alice"
      },
      {
        "id": "101",
        "title": "Understanding GraphQL Interfaces"
      }
    ]
  }
}

Differenza tra Unioni e Interfacce

Sebbene le Unioni e le Interfacce sembrino simili, hanno usi diversi e caratteristiche distinte:

  1. Campi Comuni:

    • Interfacce: I tipi che implementano un’interfaccia devono condividere almeno un insieme di campi comuni.
    • Unioni: I tipi in un’unione non devono condividere campi comuni.
  2. Utilizzo:

    • Interfacce: Usate quando diversi tipi devono condividere una struttura simile e il client deve conoscere i campi comuni.
    • Unioni: Usate quando un campo può restituire più tipi, ma questi tipi non hanno campi in comune.
  3. Estensibilità:

    • Interfacce: Possono essere estese e implementate da diversi tipi, creando una gerarchia tipizzata.
    • Unioni: Permettono più libertà poiché i tipi non hanno obblighi di condividere campi.

Best Practices per Unioni e Interfacce

  1. Usa Unioni per Tipi Completamente Diversi: Se i tipi non condividono alcun campo comune, è preferibile utilizzare un’Unione.
  2. Usa Interfacce per Strutture Comuni: Se più tipi condividono un insieme di campi, un’Interfaccia ti permette di tipizzare meglio i dati e semplificare le query.
  3. Fornisci Risolutori per le Unioni e Interfacce: Nei risolutori, devi specificare come identificare e risolvere i diversi tipi all’interno delle Unioni o delle Interfacce.

Risolutore per Unioni

const resolvers = {
  SearchResult: {
    __resolveType(obj) {
      if (obj.name) {
        return "User";
      }
      if (obj.title) {
        return "Post";
      }
      return null;
    },
  },
};

In questo esempio, il risolutore per l’Unione SearchResult identifica se l’oggetto è un User o un Post in base ai campi presenti.

Risolutore per Interfacce

const resolvers = {
  Node: {
    __resolveType(obj) {
      if (obj.name) {
        return "User";
      }
      if (obj.title) {
        return "Post";
      }
      return null;
    },
  },
};

In modo simile, per l’interfaccia Node, il risolutore determina il tipo di oggetto restituendo il nome del tipo.

Conclusione

Le Unioni e le Interfacce in GraphQL sono strumenti potenti che permettono di modellare dati flessibili e ben tipizzati. Usare le Unioni ti permette di gestire campi che possono restituire più tipi diversi, mentre le Interfacce ti permettono di definire strutture comuni tra diversi tipi. Scegliere tra Unioni e Interfacce dipende dalla natura dei tuoi dati e dai campi comuni o distintivi tra i tipi. Implementando correttamente Unioni e Interfacce, puoi creare API GraphQL più robuste, flessibili e scalabili.