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

Client: autogenerate view classes from query #574

Open
benwaffle opened this issue Aug 31, 2020 · 7 comments
Open

Client: autogenerate view classes from query #574

benwaffle opened this issue Aug 31, 2020 · 7 comments
Labels
client GraphQL Client module enhancement New feature or request

Comments

@benwaffle
Copy link

benwaffle commented Aug 31, 2020

It would be useful to write the graphql query as a string and generate the view classes

val query = gql"""
{
  character("Amos Burton") {
    name
    nicknames
    origin
  }
}
"""

// autogenerate this
case class CharacterView(name: String, nickname: List[String], origin: Origin)
case class QueryResponse(character: List[CharacterView])
@ghostdogpr ghostdogpr added client GraphQL Client module enhancement New feature or request labels Sep 1, 2020
@viclovsky
Copy link

Do you have any plan to implement the feature?
Anyway, is there any workaround how to generate view classes?

@ghostdogpr
Copy link
Owner

I think that would require some macros, I have no knowledge about that (and not really willing to learn now since Scala 3 will make it obsolete :D), but open to contributions.

@askmrsinh
Copy link

askmrsinh commented Dec 1, 2020

@viclovsky @benwaffle
I am working on something like this for a project (using macros).
Right now I am able to generate case classes for simple queries but I hope to cover more complex selections in the near future. If you have any particular need/suggestion please feel free to share.

@ghostdogpr
Copy link
Owner

FYI it is now possible to generate view classes when running the code gen (it's slightly different from your example though: it generates view classes with all fields (not based on any query).

@DGolubets
Copy link

This would be a nice addition.
Maybe rather than inline, the views could be stored in files. I like the way it's implemented in https://github.com/jhnnsrs/turms for Python.

I'll give an example why I need it.
We have many GraphQL micro-services joined with Apollo Federation.
In one of my services I need to access a subset of federated schema (top query is owned by one service, but some nested fields are resolved by another).
Generating a client for the whole federated schema results in too much code and slow compilation.

So for now I just manually define my case classes for that query...

@yahor-filipchyk
Copy link

yahor-filipchyk commented Dec 20, 2024

Perhaps this is what @DGolubets is describing but I'll try to state it in Caliban's terms, having limited experience with it: this could be implemented purely as the code-gen part of Caliban.

  • In calibanSettings, specify a directory, or a wildcard pattern for the files containing not just the schema but queries and fragments.
  • Perhaps part of the config is a reference to the schema so that the generated types can refer back to the "root" schema types (I'm not sure it needs to?)
  • The generated queries are IsOperation so they can be executed directly with .toRequest
  • SelectionBuilder for the generated fragments can be used in any other query where it complies with the Origin type of the selection (I guess this is where the generated types may have to refer to the types generated for the root schema).

In other words, it'd be nice to have a "schema first" approach to using Caliban client. I find the Scala DSL cumbersome to use in many cases. Our schema is quite complex and has a lot of nesting. On the other hand, the graphql as a query language is widely used and has good IDE support with autocompletion and validations so I'd rather write the queries in gql and have the Scala code-gen + Scala compiler make sure I'm not doing anything wild. I.e. if it compiles – it's a correct query.

@ghostdogpr
Copy link
Owner

I think that approach could work. We could require all queries to be named so that we create an object for each query and put related case classes under it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
client GraphQL Client module enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

6 participants