Giter Site home page Giter Site logo

Comments (9)

dariuszkuc avatar dariuszkuc commented on June 18, 2024

👋 did you specify any query files? i.e. are there any query files under build?

from graphql-kotlin.

snowe2010 avatar snowe2010 commented on June 18, 2024

No, I don't have any query files, I thought the introspection would pull them from the endpoint. Do I have to duplicate the query files from the providing service into our codebase? Kinda defeats the purpose of introspecting the schema doesn't it?

from graphql-kotlin.

snowe2010 avatar snowe2010 commented on June 18, 2024

I added an example query in to test and it doesn't generate any of the schema, only two objects, one which isn't even valid...
image

image

while the introspected schema has over a thousand lines in it, including the Product object.
image

from graphql-kotlin.

snowe2010 avatar snowe2010 commented on June 18, 2024

Ok, yeah so it's looking like I'm going to have to manually copy and paste every single query in to get it to generate the proper schema... That's quite annoying to say the least... Why doesn't it generate the schema without query files? I shouldn't have to generate a client just to get schema objects, especially if I want to do something with those schema objects outside of the ktor or spring ecosystem.

from graphql-kotlin.

dariuszkuc avatar dariuszkuc commented on June 18, 2024

I think you misunderstood what this library is about - graphql-kotlin is a code-first GraphQL library meaning your schema is auto-generated from your source code (through reflection), i.e. you write functions returning data and it will automatically map it to a corresponding GraphQL representation. While we do provide Spring and Ktor integrations, you can easily integrate this schema codegen capability with any server of your choice. Since schema artifact is often useful in other tooling (e.g. for schema checks), schema (in SDL format) can be generated at build time using one of the provided plugins (or you can use 3rd party tool to download the incomplete* schema through introspection) but it is an artifact of a build and not the input.

graphql-kotlin also provides simple client which relies on auto-generated client code to interact with your server (which you tried to use). Client codegen should generate valid code though so there might be a bug there as you shouldn't get empty data class like that (is query valid?).

To reiterate -> graphql-kotlin does not generate any server code. If you prefer SDL first solution (i.e. start from a schema vs code) then you might want to take a look at Netflix DGS which also provides some codegen capabilities.

*introspection does not contain any custom directive information

from graphql-kotlin.

snowe2010 avatar snowe2010 commented on June 18, 2024

I understand it's not a server solution. I'm not a acting as a server in this instance. I'm acting as the client. I would assume that as a client, I should be able to take an introspected schema (from the providing server) and generate a client data model that I can then use as I want. I don't understand your comment "graphql-kotlin is a code-first GraphQL library meaning your schema is auto-generated from your source code (through reflection)" as that's the exact opposite of what a client should need to do. If I consume a swagger-api, then I should be able to take that swagger spec and generate a model off of it, as a client, and then use that model to communicate however I want. But in this case it seems I have to provide significant details on my side copying the actual queries that the server supports in order to get any model generated.

In the past (2017 or thereabouts) I used an apollo solution that literally just generated a model. It didn't generate anything else, no queries were required, so this is just really weird to me.

from graphql-kotlin.

snowe2010 avatar snowe2010 commented on June 18, 2024

I've read over the apollo kotlin docs and they're much more clear. I think I'm going to switch over to that. I see now why the newer way of doing things is to require a query, even though I honestly think that's quite ridiculous (what happens when you need to add a new query and the nullability changes?). Seems better to just make it all nullable and deal with it rather than generate models based off of a query that could change at any moment.
In any case, Apollo supports fragments which I will need if I'm going to be copy pasting queries from the other team into our codebase, else I'm going to have a maintenance nightmare. Thanks for the talk.

from graphql-kotlin.

dariuszkuc avatar dariuszkuc commented on June 18, 2024

Apologies but it looks like I misunderstood what you were trying to do (i.e. trying to generate server code matching your full GraphQL schema).

Difference between OpenAPI and GraphQL is that in the first one clients always get the complete model vs in the latter one clients have to explicitly ask for the data they want. OpenAPI also doesn't have notion of non-null. Since GraphQL is strongly typed and your clients only get the data they explicitly ask for -> in general, smart clients will only generate data models that match your existing queries, they won't generate catch-all full schema as that is not really useful for the clients. Furthermore it also has side effects for clients written in a typesafe language, i.e. if you never request a field but it is non-nullable then Kotlin code will be problematic as you will never get the value for it but Kotlin language requires a value there.

AFAIK all the smart client libs (including Apollo Client|Kotlin|iOS) will generate the code based on your queries and only on your queries.

what happens when you need to add a new query and the nullability changes?

What you are talking here is a schema evolution which is outside of client control. Depending whether it is null->non-null or non-null->null it can be fine (first one) or a breaking change (the latter). There are other tools to detect this but in general schema owners should try to not break their clients (and at least communicate breaking changes in advance using @Deprecated).

Seems better to just make it all nullable and deal with it rather than generate models based off of a query that could change at any moment.

If you do this then you loose all the type safety information from the schema -> if everything is always nullable whats the point of having fields non-nullable? Isn't the whole point of getting non-nullable fields to indicate that you don't have to wrap it in if != null checks everywhere?


re: Apollo Kotlin -> indeed that is a much more advanced client with a number of additional features that is constantly improving. Intent behind graphql-kotlin was to provide a very simple client to handle some basic use cases but indeed it is pretty limited.

from graphql-kotlin.

snowe2010 avatar snowe2010 commented on June 18, 2024

OpenAPI also doesn't have notion of non-null.

openapi supports nullability just fine. The openapi-generator generates kotlin models perfectly fine with nullable and non-nullable fields. You just have to specify in the spec if it's nullable, else it defaults to non-nullable.

AFAIK all the smart client libs (including Apollo Client|Kotlin|iOS) will generate the code based on your queries and only on your queries.

I had tested a previous library a few months ago that generated java models just fine and did not require a query. That's most likely because they are less concerned with nullability, or because they understand that model generation is often desired even when you have no queries yet.

What you are talking here is a schema evolution which is outside of client control. Depending whether it is null->non-null or non-null->null it can be fine (first one) or a breaking change (the latter). There are other tools to detect this but in general schema owners should try to not break their clients (and at least communicate breaking changes in advance using @deprecated).

no I'm not talking about schema evolution. I'm talking about a case like this:

you have an underlying model on the server like this:

data class A(
  firstName: String? = null,
  lastName: String? = null,
  state: String? = null,
  zipCode: String? = null,
)

and in the client that is using either expedia or apollo you specify a query like so:

query A {
  firstName
  state
}

Which would generate a model like so for the server.

data class A(firstName: String, state: String)

but then later someone else in your codebase comes in and adds a new query like this to the client (the server does not change. The model is still as listed above):

query B {
 firstName
 lastName
 zipCode
}

which would generate a completely different model, even though they are the same underlying object

data class B(firstName: String, lastName: String?, state: String?, zipCode: String)

Your nullability for the same object has changed because the objects aren't actually the same. I'm not sure it would actually generate like this, I haven't tested it, but I'm just showing the issues with this query first methodology. You have no clue how the queries are going to be used, modified etc, and what the nullability actually is, especially since the query isn't coming from what the server actually supports, but is instead coming from just that one use case. Either you can then share models, or the nullability of the model changes breaking things later.

from graphql-kotlin.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.