php - platzi - que es apollo graphql
¿Cómo consultar todos los campos de tipo GraphQL sin escribir una consulta larga? (4)
Desafortunadamente, lo que te gustaría hacer no es posible. GraphQL requiere que sea explícito al especificar qué campos desea que devuelva su consulta.
Suponga que tiene un tipo GraphQL e incluye muchos campos. ¿Cómo consultar todos los campos sin escribir una consulta larga que incluya los nombres de todos los campos?
Por ejemplo, si tengo estos campos:
public function fields()
{
return [
''id'' => [
''type'' => Type::nonNull(Type::string()),
''description'' => ''The id of the user''
],
''username'' => [
''type'' => Type::string(),
''description'' => ''The email of user''
],
''count'' => [
''type'' => Type::int(),
''description'' => ''login count for the user''
]
];
}
Para consultar todos los campos, generalmente la consulta es algo como esto:
FetchUsers{users(id:"2"){id,username,count}}
Pero quiero una forma de tener los mismos resultados sin escribir todos los campos, algo como esto:
FetchUsers{users(id:"2"){*}}
//or
FetchUsers{users(id:"2")}
¿Hay alguna manera de hacer esto en GraphQL?
Estoy usando la biblioteca Folkloreatelier / laravel-graphql .
Enfrenté este mismo problema cuando necesitaba cargar los datos de ubicación que había serializado en la base de datos desde la API de Google Places. En general, me gustaría todo para que funcione con los mapas, pero no quería tener que especificar todos los campos cada vez.
Estaba trabajando en Ruby, así que no puedo darle la implementación de PHP, pero el principio debería ser el mismo.
Definí un tipo escalar personalizado llamado JSON que simplemente devuelve un objeto JSON literal.
La implementación de ruby fue así (usando graphql-ruby)
module Graph
module Types
JsonType = GraphQL::ScalarType.define do
name "JSON"
coerce_input -> (x) { x }
coerce_result -> (x) { x }
end
end
end
Luego lo usé para nuestros objetos así
field :location, Types::JsonType
Sin embargo, usaría esto con moderación, usándolo solo donde sabe que siempre necesita todo el objeto JSON (como lo hice en mi caso). De lo contrario, está derrotando el objeto de GraphQL en términos más generales.
Sí, puedes hacer esto usando introspection . Realice una consulta GraphQL como (para el tipo UserType )
{
__type(name:"UserType") {
fields {
name
description
}
}
}
y obtendrá una respuesta como (los nombres de campo reales dependerán de su esquema real / definición de tipo)
{
"data": {
"__type": {
"fields": [
{
"name": "id",
"description": ""
},
{
"name": "username",
"description": "Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only."
},
{
"name": "firstName",
"description": ""
},
{
"name": "lastName",
"description": ""
},
{
"name": "email",
"description": ""
},
( etc. etc. ...)
]
}
}
}
Luego puede leer esta lista de campos en su cliente y generar dinámicamente una segunda consulta GraphQL para obtener todos estos campos.
Esto depende de que usted sepa el nombre del tipo para el que desea obtener los campos; si no conoce el tipo, puede obtener todos los tipos y campos juntos mediante la introspección como
{
__schema {
types {
name
fields {
name
description
}
}
}
}
NOTA: estos son los datos GraphQL over-the-wire: usted está solo para descubrir cómo leer y escribir con su cliente real. Es posible que su biblioteca de JavaScript GraphQL ya emplee la introspección de alguna manera, por ejemplo, el comando codec de Apollo usa la introspección para generar tipos.
Supongo que la única forma de hacer esto es mediante la utilización de fragmentos reutilizables:
fragment UserFragment on Users {
id
username
count
}
FetchUsers {
users(id: "2") {
...UserFragment
}
}