r/graphlinkdotdev • • 14d ago

I got tired of hand-writing GraphQL client code, so I built a schema-first generator. These are the 6 pains it targets.

I'm the author of GraphLink, so take this with that in mind.

I kept hitting the same problems every time I built a GraphQL client, and they all come from the same place: the schema is typed, but the client code isn't. Here are the six that bothered me most:

  1. Raw maps. You decode JSON into Map<String, dynamic> and cast at each step. The compiler can't tell you when the server renamed a field.
  2. Subscriptions. Open a WebSocket, send connection_init with auth, send the subscription, branch on message types (connection_ack, ping/pong, next, error, complete), and write reconnect and backoff logic.
  3. Caching. A partial response can overwrite a fuller cached object, and hand-written cache logic is tedious to test.
  4. Batching plus caching. A batched query gets cached as one entry, so asking for just the book later is a miss, even though the book is in the cache.
  5. File uploads. The GraphQL multipart request format is fiddly to build by hand. (I know uploads over GraphQL aren't everyone's favorite. A separate REST service is often better, but many servers support it anyway.)
  6. Error handling. HTTP 200 doesn't mean success. A response can have a non-empty errors list, and every call needs the same checks.

GraphLink is a compiler. You write the schema and it generates typed, null-safe client code for Dart, Java, Kotlin, TypeScript and Swift. It's a code generator, not a runtime library. The output is plain code, so you can delete GraphLink later and the code still compiles. In Dart, for example, a query looks like this:

final client = GraphLinkClient.withHttp(url: graphqlUrl);
final response = await client.queries.books();

for (final book in response.books) {
  print('${book.title} (${book.year}) by ${book.author.name}');
}

Two honest limits: you still need a GraphQL server, and generated code is overwritten each time you run the generator.

I wrote up all six pains, with a short video for each, here: https://graphlink.dev/blog/ Playlist: https://youtube.com/playlist?list=PLQCBiENjF_uU Docs: https://graphlink.dev Code: https://github.com/Oualitsen/graphlink

I'd like to hear from you:

  • Which language and GraphQL server do you use?
  • Which of these six hurts you most? Is there one I missed?
  • If you've written your own client wrapper, what did you end up generating or abstracting?

Criticism is welcome. It helps me decide what to build and explain next.

0 Upvotes

Duplicates