Fragments do GraphQL: nomeados, inline e type conditions | We.Inc
Monte fragments do GraphQL em um construtor de queries ao vivo: fragments nomeados para reutilizar, inline fragments para unions e interfaces, type conditions, __typename e variáveis.
Um fragment do GraphQL é um conjunto nomeado e reutilizável de campos para um tipo, escrito como fragment Name on Type e incluído em uma query com ...Name. Um inline fragment, escrito ... on Type, não tem nome e seleciona campos só quando o resultado é aquele tipo concreto, que é como você consulta unions e interfaces.
Formas de fragment
Forma
Sintaxe
Use para
Fragment nomeado
fragment UserCard on User { ... }
Compartilhar uma lista de campos entre queries
Spread
...UserCard
Incluir os campos de um fragment nomeado
Inline fragment
... on Photo { url }
Campos de um membro de uma union ou interface
Inline sem tipo
... @include(if: $full) { bio }
Aplicar uma diretiva a um grupo de campos
Nome do tipo
__typename
Diferenciar os membros de uma union na resposta
Marque os campos que quiser no construtor e ele escreve a query para você, uma vez com um fragment nomeado e outra com os campos digitados direto, para você ver que as duas pedem os mesmos dados. Ative a opção de resultados de busca para adicionar inline fragments sobre uma union.
Marque os campos de User que o card na sua tela mostra.
Escolha se os campos vão para um fragment nomeado ou direto na query.
Ative os resultados de busca para adicionar um campo union com um inline fragment por tipo membro.
Copie a query e rode em um schema que tenha esses tipos.
Dê aos fragments o nome do componente que os usa, como UserCard ou PostRow, para que cada parte da tela declare as próprias necessidades de dados.
Sempre adicione __typename quando selecionar de uma union ou interface; o seu código precisa dele para saber qual membro recebeu.
Fragments podem ler as variáveis da operação, então um campo de fragment pode receber um argumento como size: $avatarSize.
Um fragment não pode fazer spread de si mesmo, nem diretamente nem por meio de outro fragment. A validação rejeita o ciclo antes de qualquer execução.
Perguntas frequentes
Fragments deixam as respostas menores?
Não. Um fragment é uma ajuda para escrever a query. O servidor o expande, e a resposta fica exatamente como se você tivesse digitado os campos. Se dois spreads selecionam o mesmo campo, ele aparece uma vez.
Quando preciso usar um inline fragment?
Quando um campo retorna uma union ou uma interface e você precisa de campos que só alguns tipos membros têm. O graphql.org mostra isso com um hero que pode ser um Droid com primaryFunction ou um Human com height.
Um fragment pode ser usado em outro tipo?
Só onde ele pode se aplicar. Um fragment sobre uma interface pode ser usado com spread dentro de qualquer tipo de objeto que a implemente, mas um fragment sobre User usado dentro de uma seleção de Post falha na validação.
Onde ficam os fragments no documento?
No nível mais alto do documento, ao lado das operações, em qualquer ordem. Todo fragment definido precisa ser usado, ou o servidor rejeita o documento como inválido.
Fragments nomeados para reutilizar
Imagine que um cabeçalho de perfil, um comentário e uma lista de membros mostram um nome e um avatar. Digitar esses campos três vezes convida a divergências: uma cópia ganha um campo que as outras não têm. Um fragment sobre User guarda a lista uma vez e cada query faz o spread dele.
Apps baseados em componentes vão além. Cada componente declara o fragment de que precisa, e a query da página faz o spread dos fragments dos componentes que renderiza, então as necessidades de dados ficam ao lado do código que as usa.
Inline fragments e type conditions
A parte on Type é a type condition. Em um fragment nomeado, ela diz a qual tipo os campos pertencem. Em um inline fragment dentro de um campo union, ela faz esses campos valerem só quando o objeto é daquele tipo.
Uma busca que retorna usuários, posts e fotos é o caso clássico. A seleção lista ... on User, ... on Post e ... on Photo, cada um com os próprios campos, e o __typename diz ao cliente qual ramo cada resultado seguiu.
Schema usado pelo construtor
Uma union para resultados de busca
SearchResult pode ser um User ou um Photo, então uma seleção sobre ele precisa de inline fragments para alcançar os campos de qualquer um dos membros.
Lendo uma resposta de union
O que a busca retorna
Cada item traz só os campos do próprio ramo, mais o __typename.
Ramificando pelo __typename
O nome do tipo é a forma segura de diferenciar os membros; verificar a presença de um campo pode quebrar quando um tipo passar a tê-lo.
Construtor de queries com fragments
Campos de User a selecionar
Usar um fragment nomeado (UserCard)
Adicionar resultados de busca (union com inline fragments)
Query
Copiar query
{n} campo(s) selecionado(s), {v} linha(s) de query