logoalt Hacker News

lateforworklast Sunday at 8:31 PM7 repliesview on HN

If you generate TypeScript types from OpenAPI specs then you get contracts for both directions. There is no problem here for GraphQL to solve.


Replies

WickyNilliamslast Sunday at 11:26 PM

This is very much possible, and I have done it, and it works great once it's all wired up.

But OpenAPI is verbose to the point of absurdity. You can't feasibly write it by hand. So you can't do schema first development. You need an open API compatible lib for authoring your API, you need some tooling to generate the schema from the code, then you need another tool to generate types from the schema. Each step tends to implement the spec to varying degrees, creating gaps in types, or just outright failing.

Fwiw I tried many, many tools to generate the typescript from the schema. Most resulted in horrendous, bloated code. The official generators especially. Many others just choked on a complex schema, or used basic string concatenation to output the typescript leading to invalid code. Additionally the cost of the generated code scales with the schema size, which can mean shipping huge chunks of code to the client as your API evolves

The tool I will wholeheartedly recommend (and which I am unaffiliated beside making a few PRs) is openapi-ts. It is fast and correct, and you pay a fixed cost - there's a fetch wrapper for runtime and everything else exists at the type level.

I was kinda surprised how bad a lot of the tooling was considering how mature OpenAPI is. Perhaps it's advanced in the last year or so, when I stopped working on the project where I had to do this.

https://openapi-ts.dev/

show 2 replies
c-hendrickslast Sunday at 8:39 PM

What about the whole "graph" part? Are there any openapi libraries that deal with that?

show 1 reply
komali2last Sunday at 8:35 PM

Discovering Kubb was a game changer for me last year.

show 1 reply
iterateoftenlast Sunday at 10:10 PM

Graphql solves the problem. There is no problem here for openapi to solve.

See how that works?

show 1 reply
bastawhizlast Monday at 12:18 AM

tRPC sort of does this (there's no spec, but you don't need a spec because the interface is managed by tRPC on both sides). But it loses the real main defining quality of gql: not needing subsequent requests.

If I need more information about a resource that an endpoint exposes, I need another request. If I'm looking at a podcast episode, I might want to know the podcast network that the show belongs to. So first I have to look up the podcast from the id on the episode. Then I have to look up the network by the id on the podcast. Now, two requests later, I can get the network details. GQL gives that to me in one query, and the fundamental properties of what makes GQL GQL are what enables that.

Yes, you can jam podcast data on the episode, and network data inside of that. But now I need a way to not request all that data so I'm not fetching it in all the places where I don't need it. So maybe you have an "expand" parameter: this is what Stripe does. And really, you've just invented a watered down, bespoke GraphQL.

show 1 reply
mixedCaselast Monday at 3:42 AM

If you generate OpenAPI specs, and clients, and server type definitions from a declarative API definition made with Effect's own @effect/platform, it solves even more things in a nicer, more robust fashion.