8 minutos
GraphQL Validations Migration Guide
Pronto graph-node
admitirá una cobertura del 100% de la especificación de validaciones GraphQL.
Versiones anteriores de graph-node
no soportaban todas las validaciones y proporcionaban respuestas más gráciles, por lo que en casos de ambigüedad, graph-node
ignoraba componentes inválidos de operaciones GraphQL.
El soporte de Validaciones GraphQL es el pilar para las próximas nuevas características y el rendimiento a escala de The Graph Network.
También asegurará la determinismo de las respuestas de las consultas, un requisito clave en The Graph Network.
Habilitar las Validaciones GraphQL romperá algunas consultas existentes enviadas a la API de The Graph.
Para ser compatible con esas validaciones, por favor sigue la guía de migración.
⚠️ Si no migras tus consultas antes de que se implementen las validaciones, estas devolverán errores y podrían romper tus interfaces de usuario/clientes.
Guía de migración
Puedes utilizar la herramienta de migración CLI para encontrar cualquier problema en tus operaciones GraphQL y solucionarlo. Alternativamente, puedes actualizar el endpoint de tu cliente GraphQL para usar el endpoint https://api-next.thegraph.com/subgraphs/name/$GITHUB_USER/$SUBGRAPH_NAME
. Probar tus consultas contra este endpoint te ayudará a encontrar los problemas en tus consultas.
Not all Subgraphs will need to be migrated, if you are using GraphQL ESlint or GraphQL Code Generator, they already ensure that your queries are valid.
Herramienta de migración de la línea de comandos
La mayoría de los errores en las operaciones de GraphQL pueden ser encontrados en tu código previamente.
Por esta razón, brindamos una experiencia fluida para validar tus operaciones de GraphQL durante el desarrollo o en CI.
@graphql-validate/cli
es una herramienta CLI simple que ayuda a validar operaciones de GraphQL contra un esquema dado.
Empezando
Puedes ejecutar la herramienta de la siguiente manera:
1npx @graphql-validate/cli -s https://api-next.thegraph.com/subgraphs/name/$GITHUB_USER/$SUBGRAPH_NAME -o *.graphql
Notas:
- Configura o reemplaza $GITHUB_USER, $SUBGRAPH_NAME con los valores apropiados. Por ejemplo:
artblocks/art-blocks
- La URL del esquema de vista previa (https://api-next.thegraph.com/) proporcionada tiene una limitación de tasa alta y se descontinuará una vez que todos los usuarios se hayan migrado a la nueva versión. No lo uses en producción.
- Las operaciones se identifican en archivos con las siguientes extensiones
.graphql
,.ts
,.tsx
,.js
,jsx
(opción-o
).
Salida del CLI
La herramienta de línea de comandos [@graphql-validate/cli](https://github.com/saihaj/graphql-validate)
mostrará cualquier error en las operaciones GraphQL de la siguiente manera:

Por cada error, encontrarás una descripción, una ruta de archivo y posición, y un enlace a un ejemplo de solución (ver la siguiente sección).
Ejecuta tus consultas locales contra el esquema de vista previa
Proporcionamos un punto final https://api-next.thegraph.com/
que ejecuta una versión de graph-node
que tiene las validaciones activadas.
Puedes probar tus consultas enviándolas a:
https://api-next.thegraph.com/subgraphs/id
o
https://api-next.thegraph.com/subgraphs/name/<GITHUB_USER>/<SUBGRAPH_NAME>
Para trabajar en consultas que hayan sido identificadas como teniendo errores de validación, puedes usar tu herramienta de consulta GraphQL favorita, como Altair o GraphiQL, y probar tu consulta. Esas herramientas también marcarán esos errores en su interfaz de usuario, incluso antes de ejecutarlos.
Como resolver problemas
A continuación, encontrará todos los posibles errores de validación de GraphQL que podrían ocurrir en sus operaciones de GraphQL existentes.
Las variables, operaciones, fragmentos o argumentos GraphQL deben ser únicos
Aplicamos reglas para garantizar que una operación incluye un conjunto único de variables GraphQL, operaciones, fragmentos y argumentos.
Una operación GraphQL solo es válida si no contiene ninguna ambigüedad.
Para lograr eso, necesitamos asegurarnos de que algunos componentes en su operación de GraphQL sean únicos.
Aquí hay un ejemplo de algunas operaciones inválidas que violan estas reglas:
Nombre de consulta duplicado (#UniqueOperationNamesRule)
1# La siguiente operación viola la regla UniqueOperationName,2# ya que tenemos una sola operación con 2 consultas con el mismo nombre3query myData {4 id5}67query myData {8 name9}
Solución:
1query myData {2 id3}45query myData2 {6 # rename the second query7 name8}
Nombre de Fragmento Duplicado (#UniqueFragmentNamesRule)
1# La siguiente operación violó la regla UniqueFragmentName2query myData {3 id4 ...MyFields5}67fragment MyFields {8 metadata9}1011fragment MyFields {12 name13}
Solución:
1query myData {2 id3 ...MyFieldsName4 ...MyFieldsMetadata5}67fragment MyFieldsMetadata { # asignar un nombre único al fragmento metadatos8}910fragment MyFieldsName { #asigna un nombre único al fragment name11}
Nombre de variable duplicado (#UniqueVariableNamesRule)
1# La siguiente operación viola la regla UniqueVariables2query myData($id: String, $id: Int) {3 id4 ...MyFields5}
Solución:
1query myData($id: String) {2 # Manten la variable relevante (aquí: `$id: String`)3 id4 ...MyFields5}
Nombre de argumento duplicado (#UniqueArgument)
1# La siguiente operacion, violó la consulta UniqueArguments2myData($id: ID!) {3 userById(id: $id, id: "1") {4 id5 }6}
Solución:
1query myData($id: ID!) {2 userById(id: $id) {3 id4 }5}
Consulta anonima duplicada (#LoneAnonymousOperationRule)
Además, el uso de dos operaciones anónimas violará la regla LoneAnonymousOperation
debido al conflicto en la estructura de respuesta:
1# Esto fallará si se ejecuta en conjunto en2# una sola operación con las siguientes dos consultas:3query {4 someField5}67query {8 otherField9}
Solución:
1query {2 someField3 otherField4}
O nombra las dos consultas:
1query FirstQuery {2 someField3}45query SecondQuery {6 otherField7}
Campos superpuestos
Un conjunto de selección de GraphQL se considera válido solo si resuelve correctamente el conjunto de resultados final.
Si un conjunto de selección específico o un campo crea ambigüedad ya sea por el campo seleccionado o por los argumentos utilizados, el servicio GraphQL no podrá validar la operación.
Aquí hay algunos ejemplos de operaciones inválidas que violan estas reglas:
Alias de campos en conflicto (#OverlappingFieldsCanBeMergedRule)
1# Poner alias a los campos puede causar conflictos2# ya sea con otros alias o con otros campos que existen en el esquema de GraphQL.3query {4 dogs {5 name: nickname6 name7 }8}
Solución:
1query {2 dogs {3 name: nickname4 originalName: name # alias el original `name` field5 }6}
Campos en conflicto con argumentos (#OverlappingFieldsCanBeMergedRule)
1# Diferentes argumentos pueden llevar a diferentes datos,2# asi que no podemos asumir que los capos serán los mismos.3query {4 dogs {5 doesKnowCommand(dogCommand: SIT)6 doesKnowCommand(dogCommand: HEEL)7 }8}
Solución:
1query {2 dogs {3 knowsHowToSit: doesKnowCommand(dogCommand: SIT)4 knowsHowToHeel: doesKnowCommand(dogCommand: HEEL)5 }6}
Además, en casos de uso más complejos, se puede violar esta regla al utilizar dos fragmentos que puedan causar un conflicto en el conjunto de resultados esperado:
1query {2 # Eventualmente, tenemos dos "x" definiciones, apuntando3 # para diferentes campos!4 ...A5 ...B6}78fragment A on Type {9 x: a10}1112fragment B on Type {13 x: b14}
Además de eso, las directivas GraphQL del lado del cliente como @skip
y @include
podrían causar ambigüedad, por ejemplo:
1fragment mergeSameFieldsWithSameDirectives on Dog {2 name @include(if: true)3 name @include(if: false)4}
Puedes leer mas sobre el algoritmo aqui.
Variables o fragmentos no utilizados
Una operación GraphQL también se considera válida solo si se utilizan todos los componentes definidos en la operación (variables, fragmentos).
Aquí hay algunos ejemplos de operaciones de GraphQL que violan estas reglas:
Variable no utilizada (#NoUnusedVariablesRule)
1# Inválido, porque $someVar nunca se usa.2consulta algo($someVar: String) {3 someData4}
Solución:
1query something {2 someData3}
Fragmento no Utilizado (#NoUnusedFragmentsRule)
1#Inválido, ya que el fragmento AllFields nunca se utiliza.2query something {3 someData4}56fragment AllFields { # unused :(7 name8 age9}
Solución:
1# Invalido, porque el fragmento AllFields nunca se utiliza.2query something {3 someData4}56# elimina el fragmento `AllFields`
Conjunto de selección inválido o faltante (#ScalarLeafsRule)
Además, una selección de campos GraphQL solo es válida si se valida lo siguiente:
- Un campo de objeto debe tener un conjunto de selección especificado.
- Un campo de borde (escalar, enum) no debe tener un conjunto de selección especificado.
Aquí hay algunos ejemplos de violaciones de estas reglas con el siguiente esquema:
1type Image {2 url: String!3}45type User {6 id: ID!7 avatar: Image!8}910type Query {11 user: User!12}
Conjunto de Selección Inválido
1query {2 user {3 id { # Invalido, porque "id" es de tipo ID y no tiene sub-campos45 }6 }7}
Solución:
1query {2 user {3 id4 }5}
Falta el Conjunto de Selección
1query {2 user {3 id4 image # 'image' requiere un conjunto de selección para subcampos!5 }6}
Solución:
1query {2 user {3 id4 image {5 src6 }7 }8}
Argumentos de valores incorrectos(#VariablesInAllowedPositionRule)
Las operaciones de GraphQL que pasan valores codificados a los argumentos deben ser válidas, basadas en el valor definido en el esquema.
Aquí hay algunos ejemplos de operaciones inválidas que violan estas reglas:
1query purposes {2 # si "name" esta definido como "String" en el esquema,3 # Esta consulta fallará durante la validación.4 purpose(name: 1) {5 id6 }7}89# Esto también puede suceder cuando se define una variable incorrecta:10query purposes($name: Int!) {11 # si "name" esta definido como `String` en el esquema,12 # esta consulta fallara durante la validación, por que la13 # variable usada es de tipo `Int`14 purpose(name: $name) {15 id16 }17}
Tipo, Variable, Fragmento o Directiva Desconocida (#UnknownX)
La API de GraphQL generará un error si se utiliza algún tipo, variable, fragmento o directiva desconocido.
Esas referencias desconocidas deben ser corregidas:
- renombrar si fue un error tipográfico
- de lo contrario, elimina
Fragmento: expansión o definición inválida
Extensión de fragmento no válida (#PossibleFragmentSpreadsRule)
Un fragmento no puede ser aplicado en un tipo no correspondiente.
Por ejemplo, no podemos aplicar un fragmento Cat
al tipo Dog
:
1query {2 dog {3 ...CatSimple4 }5}67fragment CatSimple on Cat {8 # ...9}
Definicion de fragento inválida (#FragmentsOnCompositeTypesRule)
Todos los fragmentos deben definirse en (usando on ...
) un tipo compuesto, en resumen: objeto, interfaz o unión.
Los siguientes ejemplos son inválidos, ya que definir fragmentos en escalares es inválido.
1fragment fragOnScalar on Int {2 # no podemos definir un fragmento sobre un escalar3(`Int`)4 something5}67fragment inlineFragOnScalar on Dog {8 ... on Boolean {9 # `Boolean` no es un subtipo de `Dog`10 somethingElse11 }12}
Uso de directivas
La directiva no puede ser utilizada en esta ubicación (#KnownDirectivesRule)
Solo las directivas GraphQL (@...
) soportadas por la API de The Graph pueden ser utilizadas.
Aqui hay un ejemplo con The GraphQL con las directivas soportadas:
1query {2 dog {3 name @include(true)4 age @skip(true)5 }6}
Note: @stream
, @live
, @defer
no son soportadas.
La directiva no puede ser utilizada en esta ubicación (#UniqueDirectivesPerLocationRule)
Los directivas soportados por The Graph solo se pueden usar una vez por ubicación.
La siguiente es inválida (y redundante):
1query {2 dog {3 name @include(true)4 age @skip(true)5 }6}