Hacker News new | ask | show | jobs
by rvcdbn 1109 days ago
I think you have to ask yourself "compared to what?".

Compared to REST, I would argue auto-generated GraphQL clients are superior (compared to auto-generated REST clients based on something like OpenAPI).

Compared to gRPC, I think it has the advantage that it's much easier to use in the browser and many people seem to prefer text-based protocols for debugability.

What are you comparing it to?

2 comments

Mostly comparing it to REST. The main turn off for me personally is it really seems like you have to reinvent the wheel to get caching to work correctly with GraphQL for non trivial use cases. Not saying that it works perfectly out of the box if you choose REST instead, but you can get pretty far without needing to optimize anything.

Why do you prefer auto-generated GraphQL clients?

auto-generated GraphQL clients works really well if you have a larger codebase and large team. You can think of it as a forced high quality documentation.

If you are working in a small project with just a few engs. The additional lift for GraphQL might not be worth it. Especially if the team is not already well versed.

I agree with you there, having GraphQL force adherence to a schema is definitely a good thing for a larger team, but smaller teams will probably get bogged down without previous experience
What I've been trying out recently is just function calls with arguments from frontend to backend.

It's only for side projects, but I personally prefer this type of approach over both REST and GraphQL.

You just have to think of it as another function.

In addition I define contract using TypeScript code something like this:

defineOperation('getPosts', { input: { filters: dataTypes.array(...) }, output: dataTypes.array(dataTypes.object({ id: dataTypes.uuid(), title: dataTypes.string()}) })

And this generates typed backend function handler and a frontend client function. Backend is TypeScript also, but it could generate for any language in theory.

I also generate database entities like that, and auto create migrations, etc. You could in theory add documentation into that defineOperation as well.

Very simple, and very smooth in my view. Also debuggable since it's text based (using POST method) with json { "operationName": "getPosts", { "filters": ... }}

In frontend I will have a generated, typed function I can use client.getPosts

and in the backend I just have to define export const getPosts: GetPosts = (requestManager) => ... where GetPosts type is generated.

It's because I think REST methods don't make much sense and the endpoints are arbitrary, in the end it's just easier to reason of everything as a function.

I also don't particularly like how GraphQL forces you into this certain mindset, that feels like in many cases it holds you back rather than makes you productive.