-
Notifications
You must be signed in to change notification settings - Fork 160
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
Custom scalar deserialization error #247
Comments
I'm not sure I understand the exact setup, correct me if I'm wrong. You have a custom scalar type that is serialized as a string in the JSON responses from your API. The right thing to do, on the client side, would be using the Ideally we would have a way to insert a One way to do it would be implement |
It's a real problem so thanks for reporting, by the way :) |
You are mostly right except juniper::graphql_scalar!(MyType {
resolve(&self) -> Value {
let s = serde_json::to_string(self).unwrap();
juniper::Value::scalar(s)
}
from_input_value(v: &InputValue) -> Option<Self> {
v.as_scalar_value::<String>().and_then(|s| {
serde_json::from_str(s).ok()
})
}
from_str<'a>(value: ScalarToken<'a>) -> juniper::ParseScalarResult<'a> {
<String as juniper::ParseScalarValue>::from_str(value)
}
}); But the Incidentally, enum MyType {
X,
Y { a: i32, b: Vec<i32> },
Z { c: String }
} etc. If there is a better way to do it, I'm all ears! I looked into using a |
Ok I think I have an idea (may be wrong). One way to "trick" serde into doing it would be, when defining your alias for the custom scalar in your client code, do something like: #[derive(Deserialize)]
struct MyType(#[serde(deserialize_with="backend_types::MyType::from_json_str")] backend_types::MyType); See https://serde.rs/field-attrs.html for the serde attribute. Since tuple structs (structs with unnamed fields) are "transparent" for serde-json, that's equivalent to redefining the deserialize implementation. Then you can define from_json_str on your type in terms of |
Even if it works it's ugly, so we should document it, and try to find a cleaner way to achieve this. |
Yes that's a decent workaround, I'll give it a go. At first I thought this PR would fix it but actually I think it would suffer the same problem. The nicest thing for the user would be to allow opaque types to be used as scalars as long as they implement |
Closing this since the issue is 5 years old. Let's open a new one to discuss similar concerns if they pop up again. |
Not sure if I'm just misunderstanding how this is supposed to work. I have a somewhat complicated type that I would like to send over GraphQL. No problem, I used the
juniper::graphql_scalar!
macro to just dump it to and load from a JSON string, seem to compile and serializes fine.But when I query the server with the client, the client doesn't use the
from_str
function, it just tries to callserde_json::from_str
on the whole graphql blob here, which of course fails because my custom type is now just a string from serde's point of view. Is this intended behavior? I expected the client to use it's own deserialization rather than rely onserde
.The text was updated successfully, but these errors were encountered: