I am creating a basic Graphql project. In this project I am only fetching user details. The data is stored in database. Here is the GQL schema:
type User {
id: ID!
username: String!
email: String!
age: Int
address : String
firstname: String
lastname :String
}
type Query {
getUserById(id: ID!): User
}
When client queries my endpoint there will be 2 connection involved.
Connection 1: From/to user to my resolver.
Connection 2 : From/to my resolver to my database.
Graphql will help me save bandwidth of Connection 1 if I am not requesting some fields.
But, in Connection 2 same amount data will be requested and fetched every time because the same sql query is running for ever request.
For example,
This query
query {
getUserById(id: "your_user_id_here") {
id
username
email
age
}
}
And this query
query {
getUserById(id: "your_user_id_here") {
id
username
email
age
address
firstname
lastname
}
}
Both trigger the same resolver function in my backend which will run the same sql query( select id, email, username.....
) for both the cases. So am I not saving any bandwidth in Connection 2 when data requested is less. Right now my schema is small but as it will increase this becomes a much bigger problem.
The underlying libraries of my backend code will ensure only requested fields will be returned to the user. I ams using gqlgen and researched on TypeGraphQL. Both seems work the same in this regards.
My question is: am I missing some graphql concept or is this really a problem? If yes, any suggestions on how to improve my resolvers.
I researched but was not able to find any stuff.
The important bandwidth to conserve is in connection 1 as you've described it. Your GraphQL server should be near your database and connected via a high speed connection. This is typical for a 3-tier design.
As your schema gets more complex you'll end up with computed fields and related types which will get pruned (not executed) from the query plan if the client doesn't request those fields.
For example let's say that instead of storing
age
directly in the db (invariably a bad idea) you stored birth date instead (or at least birth year). Thenage
would be a computed field with its own resolver. If the client did not requestage
that resolver would not run.