Pular para o conteúdo

A consulta

A linguagem que o cliente escreve: busca, mudança, assinatura, apelidos, trechos, variáveis, diretivas e introspecção.

A consulta é um texto — ela atravessa a rede. A escrita é indentada, como a linguagem, e o : no fim marca que aquele campo tem seleção dentro.

As três operações#

OperaçãoPara quê
buscaler — sem efeito colateral
mudancaescrever — o efeito aparece no nome
assinaturaacompanhar — o servidor empurra cada novo valor

A separação não é burocracia. Quem lê a consulta sabe, sem abrir o resolvedor, se aquilo muda alguma coisa — e é o que permite a um intermediário guardar em cache uma busca e nunca uma mudanca.

consulta lavra
busca:
    usuario(id: 1):
        nome

mudanca:
    criarUsuario(dados: {nome: "Ana", email: "ana@forja.co"}):
        id

assinatura:
    pedidoCriado:
        numero
        total

Campos e argumentos#

consulta lavra
busca:
    pedidos(limite: 10, ordem: Recente, ativo: yes):
        numero
        itens:
            quantidade
            produto:
                nome

Um campo sem seleção é uma folha (numero); um com seleção termina em :. É a mesma regra do bloco na linguagem, e o erro de esquecer os dois pontos diz isso.

Os valores aceitos são os da linguagem: texto entre aspas, número, yes/no/void, [lista], {vault}, $variavel e o nome de um membro de enum.

Apelidos#

consulta lavra
busca:
    ana: usuario(id: 1):
        nome
    bia: usuario(id: 2):
        nome
text
{ana: {nome: Ana}, bia: {nome: Bia}}

Sem apelido, os dois usuario colidiriam na resposta. É também como se pede o mesmo campo com argumentos diferentes na mesma consulta.

Trechos#

Um trecho é um pedaço de seleção com nome. Ele existe para não repetir a mesma lista de campos em cinco lugares — e para que mudá-la seja uma edição só.

consulta lavra
trecho Basico em Usuario:
    id
    nome
    email

busca:
    ana: usuario(id: 1):
        ...Basico
    bia: usuario(id: 2):
        ...Basico
        criado_em

O em Usuario diz a que tipo ele se aplica, e é o que permite conferi-lo antes de rodar: um trecho de Usuario usado num Produto é recusado pela validação.

Trecho condicional#

Para união e contrato: pedir o que só existe num dos tipos.

consulta lavra
busca:
    acervo:
        titulo
        ... em Video:
            minutos
        ... em Podcast:
            episodio

Variáveis#

A consulta é uma só; o valor muda. É o que permite guardá-la como constante no cliente em vez de montá-la com concatenação — que é de onde vem injeção.

consulta lavra
busca Painel($id: Integer!, $limite: Integer := 3):
    usuario(id: $id):
        nome
        pedidos(limite: $limite):
            numero
dataforge
r := Lavra.executar(esq, consulta, variaveis := {"id": 7})
DeclaraçãoO que acontece se não vier
$id: Integer!a consulta é recusada
$id: Integerchega como void
$id: Integer := 3chega como 3

Diretivas#

consulta lavra
busca Talvez($detalhado: Boolean!):
    usuario(id: 1):
        nome
        email @incluir(se: $detalhado)
        telefone @pular(se: $detalhado)

@incluir(se:) põe o campo quando a condição é verdadeira; @pular(se:) tira. Servem para uma consulta só atender a duas telas — a compacta e a completa — sem duas versões dela para divergirem.

Diretivas próprias entram no esquema:

dataforge
action so_admin(args, ctx):
    yield ctx["papel"] is "admin"

Lavra.diretiva(esq, "admin", so_admin)
consulta lavra
busca:
    usuario(id: 1):
        nome
        cpf @admin

É o gancho para @admin, @experimento(nome: …) e afins — sem espalhar given por dentro de cada resolvedor.

Introspecção#

O esquema se descreve, e é ele mesmo quem responde:

consulta lavra
busca:
    __tipo(nome: "Pedido")
consulta lavra
busca:
    __esquema

Sem introspecção, um cliente precisa de documentação ao lado para saber o que pedir — e essa documentação envelhece em silêncio. Com ela, o editor completa o campo e a página de referência é gerada do que está no ar.

A resposta vem do mesmo objeto que executa. Não há um segundo lugar descrevendo o esquema para divergir do primeiro.

Os erros de consulta dizem a linha#

text
erro: 'Usuario' não tem o campo 'nomee'
  linha 3
  dica: você quis dizer 'nome'?

E todos de uma vez: um validador que para no primeiro erro faz corrigir uma linha por tentativa. Com dez numa resposta, corrigem-se as dez.