Enum e Scalar in GraphQL: Guida Completa
In GraphQL, i tipi Enum e Scalar offrono potenti strumenti per migliorare la definizione dei dati e vincolare i valori nei tuoi schemi. Mentre i tipi Enum consentono di limitare i valori di un campo a un insieme predefinito di opzioni, i tipi Scalar permettono di estendere i tipi di base di GraphQL con comportamenti personalizzati. In questa guida, esploreremo come utilizzare Enum e Scalar in GraphQL, come definirli e implementarli, e quando è opportuno usarli.
1. Tipi Enum in GraphQL
Un Enum (enumeration) è un tipo speciale in GraphQL che rappresenta un insieme predefinito di valori possibili per un campo. Gli Enum sono utili quando si vuole limitare i valori accettabili per un campo a un insieme ristretto di opzioni.
1.1. Definire un Tipo Enum
Definire un Enum in GraphQL è semplice. Si utilizza la parola chiave enum
seguita dal nome del tipo e dall’elenco dei valori possibili.
Esempio di Definizione di un Enum
Supponiamo di avere un sistema di gestione degli ordini in cui ogni ordine può avere uno stato specifico (PENDING
, SHIPPED
, DELIVERED
, CANCELLED
).
enum OrderStatus {
PENDING
SHIPPED
DELIVERED
CANCELLED
}
1.2. Utilizzare un Enum in un Tipo
Un Enum può essere utilizzato come tipo di un campo all’interno di un tipo oggetto.
Esempio di Utilizzo di un Enum
type Order {
id: ID!
status: OrderStatus!
total: Float!
}
In questo esempio, il campo status
può assumere solo uno dei valori definiti in OrderStatus
.
1.3. Vantaggi degli Enum
- Validazione Automatica: Gli Enum limitano automaticamente i valori accettabili per un campo, garantendo che i dati siano sempre validi.
- Chiarezza del Codice: Utilizzare Enum rende il codice più leggibile e comprensibile, in quanto i valori possibili sono espliciti nello schema.
- Compatibilità con i Client: Gli Enum aiutano a garantire che i client e i server siano sempre sincronizzati sui valori accettabili per un campo.
1.4. Esempio di Query con Enum
query GetOrders {
orders {
id
status
total
}
}
1.5. Esempio di Mutazione con Enum
mutation UpdateOrderStatus($id: ID!, $status: OrderStatus!) {
updateOrderStatus(id: $id, status: $status) {
id
status
}
}
In questo esempio, la mutazione updateOrderStatus
accetta un valore OrderStatus
per aggiornare lo stato di un ordine.
2. Tipi Scalar in GraphQL
I tipi Scalar in GraphQL sono i tipi di dati primitivi, come Int
, Float
, String
, Boolean
, e ID
. GraphQL consente anche di definire tipi Scalar personalizzati per gestire dati specifici che richiedono validazione o formattazione particolari.
2.1. Scalar Predefiniti
I tipi Scalar predefiniti in GraphQL sono:
- Int: Un numero intero.
- Float: Un numero a virgola mobile.
- String: Una stringa di testo.
- Boolean: Un valore booleano (
true
ofalse
). - ID: Un identificatore univoco, solitamente utilizzato per chiavi primarie.
2.2. Creare un Tipo Scalar Personalizzato
Quando i tipi Scalar predefiniti non sono sufficienti, è possibile definire Scalar personalizzati per estendere le funzionalità del linguaggio.
Esempio: Scalar per Gestire Date
Supponiamo di voler gestire un campo Date
nel nostro schema.
- Definizione dello Scalar Personalizzato
scalar Date
- Implementazione in Apollo Server
const { ApolloServer, gql } = require("apollo-server");
const { GraphQLScalarType, Kind } = require("graphql");
const typeDefs = gql`
scalar Date
type Event {
id: ID!
name: String!
date: Date!
}
type Query {
events: [Event!]!
}
`;
const resolvers = {
Date: new GraphQLScalarType({
name: "Date",
description: "Custom Date scalar type",
parseValue(value) {
return new Date(value); // from client
},
serialize(value) {
return value.toISOString(); // sent to client
},
parseLiteral(ast) {
if (ast.kind === Kind.STRING) {
return new Date(ast.value); // from client query
}
return null;
},
}),
Query: {
events: () => [{ id: "1", name: "Conference", date: new Date() }],
},
};
const server = new ApolloServer({
typeDefs,
resolvers,
});
server.listen().then(({ url }) => {
console.log(`Server ready at ${url}`);
});
In questo esempio, abbiamo definito un tipo Scalar personalizzato Date
che converte una stringa in un oggetto JavaScript Date
e viceversa.
2.3. Vantaggi dei Scalar Personalizzati
- Validazione e Formattazione: I tipi Scalar personalizzati permettono di implementare logiche di validazione e formattazione direttamente nello schema.
- Riutilizzo: I Scalar personalizzati possono essere riutilizzati in tutto lo schema per gestire dati specifici, riducendo la duplicazione del codice.
3. Best Practices per l’Uso di Enum e Scalar
3.1. Usare Enum per Dati Concreti e Limitati
Quando un campo può assumere solo un numero limitato di valori concreti, usa un Enum. Questo rende il contratto tra client e server chiaro e riduce la possibilità di errori.
3.2. Definire Scalar Personalizzati per Dati Specifici
Quando un campo richiede una validazione o una formattazione specifica, considera di creare un Scalar personalizzato. Ad esempio, per gestire valori come Email
, URL
, o Currency
, i Scalar personalizzati sono ideali.
3.3. Documentare i Tipi Enum e Scalar
Assicurati di aggiungere descrizioni ai tuoi tipi Enum e Scalar personalizzati per aiutare gli sviluppatori a comprendere il loro scopo e il loro utilizzo.
3.4. Considerare la Compatibilità del Client
Quando aggiungi nuovi Enum o Scalar personalizzati, considera come i client esistenti gestiranno questi cambiamenti. Mantieni la retrocompatibilità quando possibile, e depreca i tipi obsoleti prima di rimuoverli.
Conclusione
I tipi Enum e Scalar in GraphQL offrono strumenti potenti per definire tipi di dati più rigidi e gestire casi d’uso specifici all’interno dello schema. Utilizzando correttamente questi tipi, puoi migliorare la robustezza, la leggibilità e la manutenibilità della tua API. Con le best practices e gli esempi forniti in questa guida, sarai in grado di integrare Enum e Scalar personalizzati nelle tue applicazioni GraphQL in modo efficace.