Hacker News new | ask | show | jobs
by Jonovono 923 days ago
I never really got graphql until I stumbled upon Wundergraph. (https://github.com/wundergraph/wundergraph). I have no affiliation with them except that I have been building an app with it. I'm honestly puzzled how it's not more popular. Maybe people are solving these problems in other ways? But I tried out a bunch of stuff: Vapor, Supabase, Hasura, firebase, nhost, etc. None of it simplifies building complex systems the way WG does.

Once I ship I plan to put together a nice sample repo talking about why I like it, but you can see the WIP here of how I use WG to build a system with (potentially) multiple databases being consumed in a type safe manner from my ios app, nextjs app (and anything else)

https://github.com/Jonovono/WGStack

3 comments

So...you've got a thick abstraction layer on the front end calling into a thick abstraction layer on the back end, and it's all congealing together the results of different API calls? And it's all done by a third-party library?

This seems like such a vastly overcomplicated way of doing things that I cannot fathom it. Throw GQL in the mix (which is already itself a thick abstraction layer), and it overwhelms me. The number of implicit failure cases, alone, makes my head spin.

Maybe I'm old school, but my solution is to write a bespoke version of what the kids call a "back end for front end" that calls the APIs, handles the error cases, and consolidates the data into a single REST endpoint built-to-purpose. You don't need GQL. You don't need a library. It makes your life less complicated -- you have a single endpoint to test, there's no leakage of the back end into the front end, and it's easy to get things (like, say, logging and analytics) without depending on expensive JS proxies such as Segment.

The only difficulty is that your back end engineers and your front end engineers have to actually talk to each other and coordinate (to be fair, this seems to be the difficulty driving 95% of this stuff: the front end engineers want to make arbitrary changes without depending on coordinating changes in the back-end API.)

haha, I don't disagree. What makes it "simple" is the code generation, abstractions etc thats going on. But ya, thats also what makes it complex. At the end of the day tho, I feel like the complexity is going to be somewhere. Especially for a small team (single dev), I don't know any other better system.

Either you will have complexity maintaining a bunch of endpoints, keeping track of where each one is used, what is returned, where the contracts are defined, writing tests to make sure nothing breaks, .... Sure, you might not have much abstraction and it will be cleaner that way, but it will be a nightmare to maintain, especially in the phase when you are moving fast and breaking things as you find market fit

Or you can rely on heavy abstraction and code generation with end to end type safety so if you change something you instantly know if you broke anything at compile/deploy time (or earlier).

Something about building this way is really nice, and quite different than anything else. Personally, i'm betting big on code gen. If coding behind layers of abstractions make you uncomfortable, whats coming down the pipeline is going to be giving you nightmares (https://twitter.com/hrishioa/status/1748346491528532344)

> Either you will have complexity maintaining a bunch of endpoints, keeping track of where each one is used, what is returned, where the contracts are defined, writing tests to make sure nothing breaks, .... Sure, you might not have much abstraction and it will be cleaner that way, but it will be a nightmare to maintain, especially in the phase when you are moving fast and breaking things as you find market fit

Yeah, I hear this argument a lot, but it hasn't been a problem in my lived experience. Certainly for small teams (and absolutely for apps written by one person), it's not that hard to keep track of the endpoints. Even for larger orgs, teams tended to want to keep their endpoint counts low, and would push back on the sorts of expansions in back-end complexity that these frameworks (i.e. GQL) make "easy" (but in reality, just kick the technical complexity can down the road; it's a lot easier to see the horrible DB queries when they're not invented dynamically by the one GQL query you didn't think of, written by some Future Intern who doesn't know any better).

I can see how this becomes more of a concern when you've got a massive org that has doubled down on microservices, but that's not most orgs.

That's fair. In my experience, once the endpoints get above a handful id rather not have to keep that all in working memory. And say you have several clients: android, ios, web, internal tooling, cli, rebase, etc. You make a change to 1 endpoint, now you have to remember everywhere you consume that client? Even 5 endpoints, 5 clients things are getting complex to keep in your head.

I'd much rather if I make a change to an endpoint, my project literally won't build and my IDE yells at me. I can make sweeping changes and go to sleep knowing I didn't mess anything up. And I know if I bring another engineer on, they can make sweeping (or tiny) changes and not have to know all of the places that consume that.

I should also note that WG doesn't require graphql. I have a few graphql operations, but you could use it completely without any graphql operations.

> I'd much rather if I make a change to an endpoint, my project literally won't build and my IDE yells at me. I can make sweeping changes and go to sleep knowing I didn't mess anything up. And I know if I bring another engineer on, they can make sweeping (or tiny) changes and not have to know all of the places that consume that.

I think you're making an allusion to GQL typing here, which I grant. A big downside of REST+JSON is that you've pushed most of the "interface contract" to the structure of the JSON file.

> I should also note that WG doesn't require graphql.

Sure. The common element to both (for me) is the layering of abstractions that hide what's really going on.

It's not GQL typing. None of my clients make GQL requests. I don't have apollo or any other junky Graphql client anywhere in my clients. All my clients still just make simple rest rpc requests. The benefit is that I have generated these clients to make these requests from simple typescript operations, or graphql operations (which the GQL is just specified on the server)

Ya, for rest and json that was my challenge. I liked the idea of openapi, but manually creating openapi docs was just not much fun.

If you are really curious about WG approach this is a good intro: https://www.youtube.com/watch?v=m3YrZav5-CU. They have some contrarian takes within the graphql community

I've worked on two projects so far that seriously considered GraphQL. The first I was involved in from the start, and we seriously thought GraphQL was something we needed, but after looking closely at it we backed off, because it really sounded like a lot of work for no real gain.

The second I wasn't part of when they made the decision, and they decided to use GraphQL and now regret it. It works, but it makes things very complicated. We're a single large team responsible for both the front and back end (in fact, two front ends).

GraphQL seems mostly important when front and back end have separate teams (possibly even at different companies) and the front end needs very specific custom data from the back end.

I'm one of the WG founders. Thanks for the mention. In case anybody has a question, please ask. (I'm getting a notification if you use the term "WunderGraph")
> I'm getting a notification if you use the term "WunderGraph"

What happens if I say it three times in a row?

Will it summon you to appear in my geographical proximity?

WunderGraph WunderGraph WunderGraaaaaaAAAAHHH-

If you say it 3 times, one of the founders will appear behind you with a Federetzel

https://twitter.com/meixnertobias/status/1704565814022770857

Say it 5 times and a genie appears who creates you a federated Graph of 100 Microservices although a single boring monolith would have been enough.
Using manifold-graphql[1], at least on the client side, has had a similar productivity gain here.

1. https://github.com/manifold-systems/manifold/tree/master/man...

I'll take a look. What I like about WG is with the defined operations on the server, I then get a typed client I can use in Typescript, Openapi (which I can use to generate clients for ios, android, etc), I get postman collection. Pretty much any client I want to consume my api from, I have a client ready to go. Now, I make changes to any of my operations, my clients will complain.
manifold does the same by working directly from graphql, no codegen steps to screw sync. if changes are made to graphql definitions, the client fails to compile.
ah, sounds interesting thanks. Will give it a look!