Variabili dinamiche
La query GraphQL seguente riceve la variabile $limit per sapere quanti articoli recuperare, e il tipo della variabile, Int, deve essere dichiarato nell'operazione:
query GetPosts($limit: Int) {
posts(limit: $limit) {
id
title
}
}Questo è il comportamento previsto in GraphQL, in cui forniamo il valore della variabile in un dizionario JSON definito nello stesso documento:
{
"limit": 3
}Questo è un comportamento "statico", condiviso da molti linguaggi. In PHP, per esempio, gli argomenti delle funzioni possono indicare il loro tipo, come nel codice qui sotto, dove l'input $number è definito come un intero:
function double(int $number): int
{
return $number * 2;
}Ora, quando dichiariamo una variabile all'interno del corpo della funzione PHP, non indichiamo il suo tipo; il tipo della variabile è determinato dal contesto in cui viene utilizzata. Nel codice qui sotto, l'assegnazione di un valore intero a $double renderà questa variabile un intero:
function double(int $number): int
{
// This var is an integer, but we don't need to declare it
$double = $number * 2;
return $double;
}Grazie alle direttive personalizzate, il server GraphQL può fornire un comportamento simile e supportare le variabili dinamiche, dove una variabile dinamica ottiene il suo valore durante la risoluzione della query nel server, invece di essere fornita dal client.
L'estensione Esecuzione di Query Multiple di Gato GraphQL include la direttiva personalizzata @export, che consente di esportare il valore di un campo in una variabile (dinamica), per poi leggere il valore di questa variabile in un argomento di campo di un'operazione diversa:
query ExportLoggedInUserName {
me {
name @export(as: "userName")
}
}
query GetPostsContainingString
@depends(on: "ExportLoggedInUserName")
{
posts(filter: { search: $userName }) {
id
title
}
}La variabile $userName è dinamica e non è necessario definire il suo tipo (String) nell'operazione che la utilizza (GetPostsContainingString). Il server GraphQL comprende già il contesto.
Se proviamo a utilizzare il valore della variabile con un tipo non corrispondente, come nella query seguente (dove ci si aspetta un Int ma la variabile dinamica è una String):
query ExportDynamicVariable {
_echo(value: "Hello world!") @export(as: "stringVar") # Exported: String
}
query UseVariable
@depends(on: "ExportDynamicVariable")
{
posts(
pagination: {
limit: $stringVar # Expected: Int, received: String
}
) {
id
}
}...allora il server GraphQL fallisce nella coercizione del valore e restituisce un errore:
{
"errors": [
{
"message": "Cannot cast value 'Hello world!' for type 'Int'",
"locations": [
{
"line": 10,
"column": 13
}
],
"extensions": {
"path": [
"{limit: $stringVar}",
"(pagination: {limit: $stringVar})",
"posts(pagination: {limit: $stringVar}) { ... }",
"query UseVariable @depends(on: \"ExportDynamicVariable\") { ... }"
],
"type": "QueryRoot",
"field": "posts(pagination: {limit: $stringVar}) { ... }",
"id": "root",
"code": "gql@5.6.1[16]",
"specifiedBy": "https:\/\/spec.graphql.org\/draft\/#sec-Values-of-Correct-Type"
}
}
]
}Specifica GraphQL
Questa funzionalità attualmente non fa parte della specifica GraphQL, ma è stata richiesta in: