Variáveis dinâmicas
A query GraphQL abaixo recebe a variável $limit para saber quantos posts recuperar, e o tipo da variável, Int, deve ser declarado na operação:
query GetPosts($limit: Int) {
posts(limit: $limit) {
id
title
}
}Esse é o comportamento esperado no GraphQL, no qual fornecemos o valor da variável em um dicionário JSON definido no mesmo documento:
{
"limit": 3
}Esse é um comportamento "estático", compartilhado por muitas linguagens. Em PHP, por exemplo, os argumentos de funções podem indicar seu tipo, como no código abaixo, onde a entrada $number é definida como um inteiro:
function double(int $number): int
{
return $number * 2;
}Agora, ao declarar uma variável dentro do corpo da função PHP, não indicamos seu tipo; o tipo da variável é determinado pelo contexto em que ela é utilizada. No código abaixo, atribuir um valor inteiro a $double fará com que essa variável seja um inteiro:
function double(int $number): int
{
// This var is an integer, but we don't need to declare it
$double = $number * 2;
return $double;
}Graças às directives personalizadas, o servidor GraphQL pode oferecer um comportamento semelhante e suportar variáveis dinâmicas, onde uma variável dinâmica obtém seu valor durante a resolução da query no servidor, em vez de ser fornecida pelo cliente.
A extensão Execução de Múltiplas Queries do Gato GraphQL inclui a directive personalizada @export, que permite exportar o valor de um campo para uma variável (dinâmica), e então podemos ler o valor dessa variável em um argumento de campo de uma operação diferente:
query ExportLoggedInUserName {
me {
name @export(as: "userName")
}
}
query GetPostsContainingString
@depends(on: "ExportLoggedInUserName")
{
posts(filter: { search: $userName }) {
id
title
}
}A variável $userName é dinâmica, e não há necessidade de definir seu tipo (String) na operação que a utiliza (GetPostsContainingString). O servidor GraphQL já compreende o contexto.
Se tentarmos usar o valor da variável com um tipo incompatível, como na query a seguir (onde um Int é esperado, mas a variável dinâmica é uma 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
}
}...então o servidor GraphQL falha ao coercionar o valor e retorna um erro:
{
"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"
}
}
]
}Especificação GraphQL
Esta funcionalidade atualmente não faz parte da especificação GraphQL, mas foi solicitada em: