Unioni e Interfacce in GraphQL: Guida Completa

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 unUsero unPost.
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
searchpuò restituire una lista di oggetti che possono essere di tipoUseroPost.
Query di Esempio
query {
search(keyword: "GraphQL") {
... on User {
id
name
}
... on Post {
id
title
content
}
}
}
In questa query:
- Utilizziamo la direttiva
... onper specificare come gestire i risultati di tipoUseroPost. - Se l’oggetto restituito è un
User, richiediamoidename. Se è unPost, richiediamoid,title, econtent.
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
Nodedefinisce un campoidche deve essere implementato sia daUserche daPost. - Sia
UserchePostdevono quindi avere un campoid.
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
nodesrestituisce una lista di oggetti che implementano l’interfacciaNode, quindi può restituire siaUserchePost.
Query di Esempio con Interfaccia
query {
nodes {
id
... on User {
name
}
... on Post {
title
}
}
}
In questa query:
- La direttiva
... onviene utilizzata per richiedere campi specifici in base al tipo di oggetto (UseroPost).
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:
-
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.
-
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.
-
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
- Usa Unioni per Tipi Completamente Diversi: Se i tipi non condividono alcun campo comune, è preferibile utilizzare un’Unione.
- 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.
- 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.