Perl6-GraphQL
Perl6-GraphQL copied to clipboard
How to use fragments
Hi Curt,
I have a question about how to use fragments especially how to specify the type on which it applies. E.g. The following query works
query pinterest ( $uri: String, $idx: Int) {
page(uri: $uri)
link(idx: $idx) {
href
text
imageList {
src
alt
}
}
}
the link
field is handled by the GraphQL::Html::QC.link
method returning a GraphQL::Html::QC::Link
object and imageList
by the GraphQL::Html::QC.imageList
method returning an Array[GraphQL::Html::QC::Image]
object.
Now I want to do this;
fragment imgs on GraphQL::Html::QC::Link {
imageList {
src
alt
}
}
query pinterest ( $uri: String, $idx: Int) {
page(uri: $uri)
link(idx: $idx) {
href
text
...imgs
}
}
This does not parse because of the used module name and when I use Link
, I get the error `No such method 'field' for invocant of type 'GraphQL::Types::GraphQL::LazyType'.
Regards, Marcel
I'll have to look at this later in more detail.
For now, you're correct, GraphQL identifiers can't include ':' characters (unfortunate for Perl). LazyType is a placeholder used during parsing. Once the actual type is defined, it replaces it. I think you're finding poor error reporting when the type is never defined. I'll try to fix that.
If you want to refer to the actual Perl class name, don't use ':' in the name. Not sure, but you might be able to create a sort of 'wrapper' class around the real class:
class Link is GraphQL::Html::QC::Link {}
Then use "Link" in the schema instead of the full name.
It runs but does not give the previous answer. It misses the imageList information. Besides I have to change things on more than one place, the data for the link is returned in a GraphQL::Html::QC::Link
object. So the fragment definition now works but is always empty because it is not the wrapped object of type 'Link'.
To let it all work I have to write all of these classes in simple one-word class names. I am not sure if this won't give too much pollution in the current namespace. Most of the time these are simple words too.
What about letting the user provide a namespace(or a list of them?) of where to find the classes?
They only need to be in the lexical namespace of the GraphQL schema. Once they are exposed through GraphQL, they all have to be unique anyway.
I've only used one word classes at the top level in my work.
I'll have to think about providing a separate namespace (or list) to look them up in. That might be possible..
I've tried something like
class GraphQL::Html::QC {
class Link { ... }
...
}
class GraphQL::Html {
has GraphQL::Schema $.schema-object;
submethod BUILD (...) {
...
$!schema-object .= new(
GraphQL::Html::QC,
GraphQL::Html::QC::Image,
GraphQL::Html::QC::Link,
:query(GraphQL::Html::QC.^name)
);
}
But this still fails because setting the schema happens outside the query class and I must provide the complete module name GraphQL::Html::QC::Link
. Therefore, the GraphQL module can stil not find the Link
type.
So, I think it is indeed necessary to help the user letting them to provide a namespace name using a named argument: :namespace, or when not provided, first a top level namespace '' and then try the namespace of the query class
Sorry wrong button.