Skip to content
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

Support scalar encoders when doing custom definitions #109

Closed
johnhydroware opened this issue Jan 22, 2019 · 2 comments
Closed

Support scalar encoders when doing custom definitions #109

johnhydroware opened this issue Jan 22, 2019 · 2 comments

Comments

@johnhydroware
Copy link

The generator needs to support custom scalar encoders as well as custom decoders to fully support custom scalar types used in both directions.

@dillonkearns
Copy link
Owner

Hello @johnhydroware, thank you for reporting the issue!

I've implemented a fix for including Encoders in addition to Decoders: #111

However, I'm not sure that it's possible to support arbitrary JSON with this design. From the details you gave me on Slack, I think you're trying to do a custom JSON scalar and trying to pass that in as a GraphQL Argument somewhere.

The design I have with #111 assumes that there is a single data type that is a source of truth for representing something in Elm. It uses that one data type as the target to decode to, and expects it as the values passed in to encode from.

For example, you could have a PosixTime custom scalar and represent it with the Posix.Time data type from elm/time. In that case, you would want to pass a Posix.Time as the starting value which you would then encode. Or if you decoded a CelsiusTemperature into a Float, you would want to define you the corresponding encoder as starting from Float. Or imagine that you have a Custom Scalar called Set (which of course represents a list of unique items). You could define a decoder which takes a list of items and turns it into a Set from the Elm core library. In this case, you would also want the encoder to take in an Elm Set and turn that into an encoded value.

I think this is a reasonable assumption, and it makes things more robust and simple.

It seems to me that JSON may be a special case. What you decode it into is an opaque value (Json.Decode.Value) which isn't accessible directly, it can only be accessed by the low-level API. So you couldn't take a Json.Decode.Value and and turn it into an encoded value as you could with the other examples I mentioned.

The reason it's different, I think, comes down to the fact that it's inherently untyped. That's exactly the purpose of Json.Decode.Value and what it represents. But if you're passing something in as an argument, it seems to me that it should be typed data. So there's a mismatch here.

Could you give me a little more detail on your use case to help me understand what type of data your sending in as a JSON argument? I would like to get a better sense of why you're using JSON there instead of typed data.

Thanks!

Dillon

@dillonkearns
Copy link
Owner

I just shipped NPM version 3.2.0 which includes the changes I described above.

Another thought, having the guarantee that the type of the Encoder matches the type of the Decoder adds an extra layer of safety if you use custom types. For example, if you define a decoder that turns something into a type GitSha = GitSha String, then it's nice to know that you will only be allowed to pass a GitSha in as an argument where that's needed.

Would love to hear your thoughts when you have a chance!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants