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

Feature request: Convenience functions for primitive comparisons #604

Closed
cllns opened this issue Jul 29, 2022 · 3 comments
Closed

Feature request: Convenience functions for primitive comparisons #604

cllns opened this issue Jul 29, 2022 · 3 comments

Comments

@cllns
Copy link
Contributor

cllns commented Jul 29, 2022

I find myself using this very often:

Api.InputObject.buildInt_comparison_exp (\args -> { args | eq_ = Present 123}

I understand this is powerful and enables complex queries, but it's also verbose for a trivial comparison.

I wonder if the basic primitives (Int, String, Date, etc), could have generated convenience functions. E.g. the above could leverage a convenience function like:

Api.Int.eq_ 123

The same would be repeated for the other operators: not equals, greater than (or equal to), less than (or equal to), is null, in list, not in list. If you need to combine them, then you need to fall-back to using buildInt_comparison_exp, but in the majority of cases, I'm doing simple comparisons that could be briefer.

These could be optionally generated (at least at first, to gain feedback) in the elm-graphql CLI command.

@cllns cllns changed the title Convenience functions for primitive comparisons Feature request: Convenience functions for primitive comparisons Jul 29, 2022
@cllns
Copy link
Contributor Author

cllns commented Jul 30, 2022

After sleeping on it, I realized I conflated Graphql with Hasura here 😅

While Hasura is very popular within the Elm community, I guess you'd be reluctant (at best) to build anything that specifically generates code for that one provider within this general purpose library. Then, the obvious move would be to build a library that builds upon this one.

The simplest (zero integration) approach seems to be: create a tool to run after elm-graphql that looks for X.InputObject.buildInt_comparison_exp (etc) with the right signature and then creates some files XHelper.Int. I think populating them in a different namespace is ideal, since I think this library wipes out all of the files each time it's run, is that right? (See below for a way around this constraint)

These primitive helper functions are relatively static so it doesn't necessarily need to be run every time elm-graphql is run. However, adding new scalars to the schema, even primitive ones, means that new comparison expression functions get generated (e.g.buildFloat_comparison_exp when a float gets added to the schema). But since these are just convenience functions, that can be a manual additional step when needed.

Also new custom scalars can be also get new comparison functions generated (e.g. Uuid, Bpchar), but those don't need to be considered for a first version, since those involve codecs.

Later, the elm-hasura CLI tool could first pass all its args to elm-graphql then runs its own pass immediately after that code is generated, rather than being a separate step. This would also let them share a namespace, X.Int as originally proposed, though I guess you'd prefer it if I stayed out of there thankyouverymuch 😉

Unfortunately this all seems like a lot of work for a minor/moderate convenience. Are there any other obvious convenience function optimizations that could be made assuming the Graphql schema adheres to the Hasura conventions (or any given set of conventions)?

Otherwise: is there any appetite for adding extension points to this library to generate some extra files? Is that even possible? Maybe a --after Hasura.GenerateHelpers.call CLI hook? Ideally this would still have some state of the schema passed into it.

This same approach could be applied to creating convenience functions for Postgraphile's similar tool, or really any Graphql schema.

I think in the meantime, I'll just make my own ApiHelper module with an int_eq function in my codebase as-needed :D

@dillonkearns
Copy link
Owner

While Hasura is very popular within the Elm community, I guess you'd be reluctant (at best) to build anything that specifically generates code for that one provider within this general purpose library. Then, the obvious move would be to build a library that builds upon this one.

Yes, I think the challenge is that there is a cost for users to learn new features, understand how they work and when to use them and what is available, and navigating through all the (already pretty complicated) generated code to find something else when they need that. I certainly think that building input objects is in general a pain-point in elm-graphql and I'm very interested in making that general functionality easier to use, but I don't see this as the path I want to go down to do that (looking at vendor-specific tools). So this isn't in the scope of what I'd consider to be part of elm-graphql, but of course you're welcome to experiment with building external tools if you think that would be helpful for your use case.

I'm keeping an eye on what Vendr is experimenting with for using the Phantom Builder Pattern to build up input objects (https://rhg.dev/blog/exploring-graphql-input/). I think they still have some problems they'll need to solve that I haven't heard an answer for so far - specifically how to deal with generating functions for working with arguments with the same name but different types within an API. I worry a bit that some of those details could end up being dead ends in that design direction, but I'm really eager to see if they're able to solve those issues because if so it could be really promising.

Otherwise: is there any appetite for adding extension points to this library to generate some extra files? Is that even possible? Maybe a --after Hasura.GenerateHelpers.call CLI hook? Ideally this would still have some state of the schema passed into it.

This is a pretty ambitious feature and I don't see a clear concrete value to it at the moment, so I'm not planning on working on something like this. It would be hard to design something without a very clear reason for it and I would need to see a lot more concrete use cases where this would be beneficial before it would seem compelling to me.

@cllns
Copy link
Contributor Author

cllns commented Aug 1, 2022

Thanks for the thoughtful reply @dillonkearns. All very reasonable!

Closing this issue.

@cllns cllns closed this as completed Aug 1, 2022
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