Docs
Buscar⌘ K
  • Início
  • Sobre o The Graph
  • Redes Apoiadas
  • Contratos de Protocolo
  • Subgraphs
    • Substreams
      • Token API
        • AI Suite
          • Indexação
            • Recursos
              Subgraphs > Queries

              9 minutos

              Etiqueta de Query

              O The Graph fornece uma maneira descentralizada de buscar dados de blockchains (queries). Os dados são expostos por uma API da GraphQL, o que facilita queries com a linguagem GraphQL.

              Aprenda as regras linguísticas essenciais da GraphQL e as melhores práticas para otimizar o seu subgraph.


              Queries numa API GraphQL

              A Anatomia de um Query em GraphQL

              Ao contrário da REST API, uma API GraphQL é construída em cima de um Schema que define quais queries podem ser realizados.

              Por exemplo, um query para retornar um token através do query token ficará assim:

              1query GetToken($id: ID!) {2  token(id: $id) {3    id4    owner5  }6}

              …assim retornando a seguinte resposta previsível em JSON (ao passar o valor variável $id apropriado):

              1{2  "token": {3    "id": "...",4    "owner": "..."5  }6}

              Queries em GraphQL usam a linguagem GraphQL, definida sobre uma especificação⁠.

              O query GetToken acima é composto de várias partes da linguagem (substituído abaixo com [...] temporários):

              1query [operationName]([variableName]: [variableType]) {2  [queryName]([argumentName]: [variableName]) {3    # "{ ... }" expressa um Selection-Set, estamos a consultar campos do `queryName`.4    [field]5    [field]6  }7}

              Regras para Escrever Queries em GraphQL

              • Cada queryName só pode ser usado uma vez por operação.
              • Cada field deve ser usado apenas uma vez numa seleção (não podemos solicitar a id duas vezes sob o token)
              • Alguns fields ou queries (como tokens) retornam tipos complexos que exigem uma seleção de sub-campo. Caso uma seleção não seja fornecida quando esperada (ou fornecida quando não é esperada — por exemplo, em id), aparecerá um erro. Para conhecer um tipo de campo, consulte o Graph Explorer.
              • Qualquer variável apontada a um argumento deve corresponder ao seu tipo.
              • Em uma lista dada de variáveis, cada uma delas deve ser única.
              • Todas as variáveis definidas devem ser usadas.

              Não seguir as regras acima causará um erro da API do The Graph.

              Para uma lista completa de regras com exemplos de código, veja o guia de Validações da GraphQL.

              Como enviar um query a uma API GraphQL

              GraphQL é uma linguagem e um conjunto de convenções transportadas através do HTTP.

              Ou seja, dá para fazer um query numa API GraphQL com o fetch normal (nativamente ou via @whatwg-node/fetch ou isomorphic-fetch).

              Porém, conforme mencionado em “Como Fazer Queries de Um Aplicativo”, recomendamos usar o graph-client, que apoia as seguintes funções únicas:

              • Gestão de Subgraph Entre Chains: Queries de múltiplos subgraphs numa única consulta
              • Rastreamento Automático de Blocos⁠
              • Paginação Automática⁠
              • Resultado totalmente digitado

              Aqui está como fazer queries para o The Graph com o graph-client:

              1import { execute } from '../.graphclient'23const query = `4query GetToken($id: ID!) {5  token(id: $id) {6    id7    owner8  }9}10`11const variables = { id: '1' }1213async function main() {14  const result = await execute(query, variables)15  // `result` is fully typed!16  console.log(result)17}1819main()

              Para mais alternativas de clientes para GraphQL, veja “Como Fazer Queries de Um Aplicativo”.


              Boas práticas

              Sempre escreva consultas estáticas

              É (um erro) comum construir strings de query dinamicamente, como no exemplo a seguir:

              1const id = params.id2const fields = ['id', 'owner']3const query = `4query GetToken {5  token(id: ${id}) {6    ${fields.join('\n')}7  }8}9`1011// Execute query...

              Enquanto o trecho acima produz um query válido na GraphQL, isto traz muitas desvantagens:

              • deixa o query mais difícil de entender
              • os programadores são responsáveis por higienizar a interpolação de string com segurança
              • não enviar os valores das variáveis como parte dos parâmetros de pedido impede um possível caching no lado do servidor
              • isto impede as ferramentas de analisar o query estaticamente (por ex. Linter ou ferramentas de geração de tipos)

              Por isto, é recomendado sempre escrever queries como strings estáticas:

              1import { execute } from 'your-favorite-graphql-client'23const id = params.id4const query = `5query GetToken($id: ID!) {6  token(id: $id) {7    id8    owner9  }10}11`1213const result = await execute(query, {14  variables: {15    id,16  },17})

              Isto traz muitas vantagens:

              • Queries fáceis de ler e manter
              • O servidor GraphQL cuida da higienização de variáveis
              • Variáveis podem ser guardadas em cache no nível do servidor
              • Queries podem ser analisados estaticamente por ferramentas (mais sobre isto nas secções seguintes)

              Como incluir campos condicionalmente em queries estáticos

              Talvez queira incluir o campo owner apenas com uma condição particular.

              Para isto, use a diretiva @include(if:...) a seguir:

              1import { execute } from 'your-favorite-graphql-client'23const id = params.id4const query = `5query GetToken($id: ID!, $includeOwner: Boolean) {6  token(id: $id) {7    id8    owner @include(if: $includeOwner)9  }10}11`1213const result = await execute(query, {14  variables: {15    id,16    includeOwner: true,17  },18})

              Observação: a diretiva oposta é @skip(if: ...).

              Pergunte pelo que queres

              A GraphQL ficou famosa por sua frase de efeito “pergunte pelo que queres”.

              Por isto, no GraphQL, não há como obter todos os campos disponíveis sem ter que listá-los individualmente.

              • Ao consultar APIs GraphQL, sempre considere fazer query apenas dos campos que serão usados.
              • Tenha certeza que os queries só retornarão o máximo necessário de entidades. Por natureza, os queries retirarão 100 entidades em uma coleção, muito mais do que realmente será usado; por ex., para fins de amostra ao usuário. Isto serve não só para coleções de alto nível em um query, mas também — especialmente — para coleções aninhadas de entidades.

              Por exemplo, no query seguinte:

              1query listTokens {2  tokens {3    # will fetch up to 100 tokens4    id5    transactions {6      # will fetch up to 100 transactions7      id8    }9  }10}

              A resposta pode conter 100 transações para cada um dos 100 tokens.

              Se o aplicativo só precisa de 10 transações, o query deve configurar explicitamente first: 10 no campo de transações.

              Use uma única query para pedir vários registros

              Por padrão, subgraphs têm uma entidade singular para um registo. Para múltiplos registos, use as entidades plurais e o filtro: where: {id_in:[X,Y,Z]} ou where: {volume_gt:100000}

              Um exemplo de query ineficaz:

              1query SingleRecord {2  entity(id: X) {3    id4    name5  }6}7query SingleRecord {8  entity(id: Y) {9    id10    name11  }12}

              Um exemplo de query otimizado:

              1query ManyRecords {2  entities(where: { id_in: [X, Y] }) {3    id4    name5  }6}

              Combine múltiplas queries em um único pedido

              O seu aplicativo pode exigir queries de múltiplos tipos de dados, como a seguir:

              1import { execute } from "your-favorite-graphql-client"23const tokensQuery = `4query GetTokens {5  tokens(first: 50) {6    id7    owner8  }9}10`11const countersQuery = `12query GetCounters {13  counters {14    id15    value16  }17}18`1920const [tokens, counters] = Promise.all(21  [22    tokensQuery,23    countersQuery,24  ].map(execute)25)

              Enquanto esta implementação é totalmente válida, ela exigirá duas rondas totais com a API da GraphQL.

              Felizmente, também vale enviar múltiplos queries no mesmo pedido à GraphQL, como a seguir:

              1import { execute } from "your-favorite-graphql-client"23const query = `4query GetTokensandCounters {5  tokens(first: 50) {6    id7    owner8  }9  counters {10    id11    value12  }13}14`1516const  { result: { tokens, counters } } = execute(query)

              Este método melhorará o desempenho em geral ao reduzir o tempo gasto na rede (porque poupa uma viagem ao redor da API) e fornecerá implementações mais concisas.

              Como Aproveitar Fragmentos GraphQL

              O GraphQL Fragment é uma ferramenta útil para a escrita de queries em GraphQL.

              No seguinte query, perceba que alguns campos são repetidos em vários Selection-Sets ({ ... }):

              1query {2  bondEvents {3    id4    newDelegate {5      id6      active7      status8    }9    oldDelegate {10      id11      active12      status13    }14  }15}

              Estes campos repetidos (id, active, status) trazem muitos problemas:

              • Queries mais extensos ficam difíceis de ler.
              • Ao usar ferramentas que geram tipos TypeScript baseados em queries (mais na última secção), newDelegate e oldDelegate retornarão duas interfaces distintas em inline.

              Fatorizado novamente, o query ficaria assim:

              1query {2  bondEvents {3    id4    newDelegate {5      ...DelegateItem6    }7    oldDelegate {8      ...DelegateItem9    }10  }11}1213# nós definimos um fragmento (subtipo) no Transcoder14# para fatorizar campos repetidos no query15fragment DelegateItem on Transcoder {16  id17  active18  status19}

              Usar o fragment (“fragmento”) da GraphQL melhorará a legibilidade (especialmente em escala) e também melhorará a geração de tipos TypeScript.

              Ao usar a ferramenta de geração de tipos, o query acima gerará um tipo DelegateItemFragment apropriado (veja a última secção “Ferramentas”).

              O que fazer e o que não fazer em Fragments GraphQL

              A base do fragment deve ser um tipo

              Um Fragment não pode ser baseado num tipo não aplicável; ou seja, um tipo sem campos:

              1fragment MyFragment on BigInt {2  # ...3}

              O BigInt é um escalar (tipo “plano” nativo) que não pode ser usado como a base de um fragmento.

              Como espalhar um Fragment

              Fragmentos são definidos em tipos específicos e devem ser usados de acordo nos queries.

              Exemplo:

              1query {2  bondEvents {3    id4    newDelegate {5      ...VoteItem # Error! `VoteItem` cannot be spread on `Transcoder` type6    }7    oldDelegate {8      ...VoteItem9    }10  }11}1213fragment VoteItem on Vote {14  id15  voter16}

              newDelegate e oldDelegate são do tipo Transcoder.

              Não é possível espalhar um fragmento do tipo Vote aqui.

              Defina o Fragment como uma unidade de negócios atômica de dados

              Fragments da GraphQL devem ser definidos com base no seu uso.

              Para a maioria dos casos de uso, definir um fragmento por tipo (no caso do uso repetido de campos ou geração de tipos) já é o suficiente.

              Aqui estão algumas regras básicas para o uso de Fragmentos:

              • Quando campos do mesmo tipo se repetem em um query, agrupe-os em um Fragment.
              • Quando campos parecidos (mas não idênticos) se repetem, crie múltiplos fragmentos, por exemplo:
              1# base fragment (mostly used in listing)2fragment Voter on Vote {3  id4  voter5}67# extended fragment (when querying a detailed view of a vote)8fragment VoteWithPoll on Vote {9  id10  voter11  choiceID12  poll {13    id14    proposal15  }16}

              Ferramentas Essenciais

              Exploradores do GraphQL baseados em web

              Pode ser até chato executar queries no seu aplicativo para iterar sobre elas. Por isto, não hesite em usar o Graph Explorer para testar os seus queries antes de adicioná-los. O Graph Explorer fornecerá um ambiente de testes GraphQL pré-configurado para testar os seus queries.

              Se procura uma maneira mais flexível de depurar/testar seus queries, há outras ferramentas semelhantes baseadas na web, como Altair⁠ e GraphiQL⁠.

              GraphQL Linting

              Para acompanhar as melhores práticas e regras sintáticas explicadas acima, vale muito a pena utilizar as ferramentas IDE e de fluxo de trabalho a seguir.

              ESLint — GraphQL

              O ESLint da GraphQL⁠ te ajudará a acompanhar as melhores práticas da GraphQL sem sofrimento.

              Organize a configuração “operations-recommended”⁠ para executar regras essenciais como:

              • @graphql-eslint/fields-on-correct-type: um campo está num tipo apropriado?
              • @graphql-eslint/no-unused variables: should a given variable stay unused?
              • e mais!

              Isto permitirá-lhe detetar erros mesmo sem testar queries no playground ou mesmo executá-los na produção!

              Plugins IDE

              VSCode e GraphQL

              A extensão VSCode da GraphQL⁠ é uma adição excelente ao seu fluxo de programação que permite:

              • Destaque de sintaxe
              • Sugestões de preenchimento automático
              • Validação perante schema
              • Snippets (blocos de código reutilizáveis)
              • Definições de fragmentos e tipos de entrada

              Se utilizar o graphql-eslint, a extensão VSCode para o ESLint⁠ é essencial para visualizar corretamente erros e avisos embutidos no seu código.

              WebStorm/Intellij e GraphQL

              O plugin JavaScript para a GraphQL⁠ melhorará muito a sua experiência com a GraphQL com:

              • Destaque de sintaxe
              • Sugestões de preenchimento automático
              • Validação perante schema
              • Snippets (blocos de código reutilizáveis)

              Para mais informações sobre este tópico, veja o artigo do WebStorm⁠, que demonstra todas as funções principais do plugin.

              ⁠Editar no GitHub⁠

              Como administrar as suas chaves de APIComo Fazer Queries de um Aplicativo
              Nesta página
              • Queries numa API GraphQL
              • A Anatomia de um Query em GraphQL
              • Regras para Escrever Queries em GraphQL
              • Como enviar um query a uma API GraphQL
              • Boas práticas
              • Sempre escreva consultas estáticas
              • Como incluir campos condicionalmente em queries estáticos
              • Pergunte pelo que queres
              • Use uma única query para pedir vários registros
              • Combine múltiplas queries em um único pedido
              • Como Aproveitar Fragmentos GraphQL
              • O que fazer e o que não fazer em Fragments GraphQL
              • A base do fragment deve ser um tipo
              • Ferramentas Essenciais
              • Exploradores do GraphQL baseados em web
              • GraphQL Linting
              • Plugins IDE
              The GraphStatusRede de TestesAtivos de MarcaFórumSegurançaPolítica de PrivacidadeAcordo de Serviço