-
Notifications
You must be signed in to change notification settings - Fork 221
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Provide a default output type for JsValue #217
Comments
Indeed, it is possible to use raw JSON data with custom scalar type, though I would discourage you from using it. By using it you are losing many benefits of GraphQL. In your case, I would suggest using interface or union types to model different shapes, points, lines, etc |
Thanks! Great example code as well. Do you really need to implement the entire custom marshall/unmarshalling system, or will just the ScalarType[JsValue] do? I agree you lose many benefits of GraphQL through this approach, but I'm not sure I see the other way. Our whole system uses Sangria/GraphQL quite successfully (thanks...it's quite well written). However, I am implementing a recursive document store, where (much like HTML/XML) each node may have a common interface but also contains an unknown chunk of data/settings. You will not know apriori which type of node you are getting back. |
Thanks! Yeah, you need to re-implement marshaller/unmarshaller because the standard one does not support raw JSON AST nodes. It may be possible to add a built-in support, but I still a bit undecided about this one. What concerns me the most is GraphQL type system is quite powerful, so it can get you pretty far. For example, it can handle abstract and recursive types. Here is an example schema: interface TreeNode {
id: ID!
name: String
}
type ParentNode implements TreeNode {
id: ID!
name: String
children: [TreeNode!]
}
type LeafNode implements TreeNode {
id: ID!
name: String
color: String
}
type Query {
root: TreeNode
} Given this schema you can execute queries like this one: {
root {
name
... on ParentNode {
children {
id, name
... on ParentNode {
children {
id
}
}
}
}
}
} If you could describe your data model in more detail, maybe I would be able to suggest something more concrete. |
Thanks for the example of recursion using fragments. It is still my understanding that GraphQL cannot handle trees of indefinite depth (see graphql/graphql-spec#91). Is that true of Sangria's implementation as well? My use case is very similar to the TreeNode example, except TreeNode is polymorphic: each node in a generic "document" is comprised of subdocuments, which are comprised of leaves that could be text, images, tables, charts, etc. Each TreeNode has a common "header" with 'name' and 'id', but each has a 'data' field that's different. 'data' looks like I'm arguably mis-using GraphQL using a recursive tree of unknown depth and polymorphism, but since the rest of our APIs use GraphQL quite successfully, I've encapsulated the polymorphism as a JsValue. I'm storing a 'nodeType' enum that effectively allows a non-Sangria Input Marshaller to turn the JsValue back into Scala classes. So, is this polymorphism justification to use raw JsValues, or is there a better approach? |
GraphQL/Sangria can handle infinite-depth trees. you just can query only several levels at a time. In general, it sounds like in your case interfaces + recursive GraphQL types should fit quite well. I guess it comes back to a client. If you can build a client in a way that only asks several levels at a time, then I think you don't need to resort to raw JSON values. |
I think on the output side, a union type will work just fine: It appears that official GraphQL does not have any support for "input unions" however (graphql/graphql-js#207). Do you have a recommended approach for handling polymorphic inputs? This is really the only reason I was tempted to go for raw Json inputs... |
Right now, the best alternative to an InputUnion for GraphQL I've come up with is something like:
Essentially we use |
Yeah, this is the issue I faced as well. Would love to see input union or interface types in the spec. |
Hi I will also will be really happy with default output type for JsValue My case is also little bit out of what GraphQL is all about when we comes to exact data fields fetch. Having selection for
|
In GraphQL, there are circumstances where you may have a large number of derived classes and you want to output the variance as a raw JSON object. I might, for example want to output a mixed bag of Shape objects, each of which is described in a different format, or having a varying number of points/lines/curves.
case class Shape(name: String, points: JsValue)
At present, GraphQL cannot output such an object as:
Can't find suitable GraphQL output type for Option[play.api.libs.json.JsValue]
It seems like this should be easy to do since JsValue is an "already-marshalled" object.
Any suggestions on how to implement?
The text was updated successfully, but these errors were encountered: