Comments (9)
👋 did you specify any query files? i.e. are there any query files under build
?
from graphql-kotlin.
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.
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...
while the introspected schema has over a thousand lines in it, including the Product object.
from graphql-kotlin.
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.
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.
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.
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.
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.
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)
- [feature] support @oneOf directive HOT 3
- Coroutine scope null HOT 3
- generator: Couldn't share Union type when includes self-reference type HOT 5
- `IllegalArgumentException` occurs on Spring Framework 6.1 when using AOP HOT 2
- Deadlock when using subscriptions with two Ktor worker threads HOT 4
- GraphQLIgnore annotation not respected when running GraalVM native image
- Spring Boot 3.1.6 health endpoint latency is very high when other query is running. HOT 10
- Unable to perform upgrade as it is not requested by the client: request should have Upgrade and Connection headers filled properly HOT 1
- [ktor server] Ability to specify custom GraphQL server
- GraphQL client gradle plugin fails to find `compileDebugKotlin` task.
- Make `src/main/resources` configurable for GraphQL clients HOT 1
- Spring WebFlux: How to autowire a service/component in a CustomDirective behavior?
- ControllerAdvice and ModelAttribute
- [generator] support directives using input object args
- GraphQL Ktor plugin swallows context exceptions. HOT 3
- Ktor: Flow/Subscription websocket stops working (Ping Timeout)
- Why do I get this error when I start the application HOT 2
- feat: allow classes corresponding to SDL to be decoupled from implementation
- Unable to retrieve federated types with apollo federation v1 HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from graphql-kotlin.