Remix.run Logo
WickyNilliams 2 days ago

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/

jcgl 2 hours ago | parent | next [-]

Agree with the other comments about writing OpenAPI by hand. It’s really not that bad at all, and most certainly not “verbose to the point of absurdity.”

Moreover, system boundaries are the best places to invest in being explicit. OpenAPI specs really don’t have that much overhead (especially if you make use of YAML anchors), and are (usually) suitably descriptive to describe the boundary.

In any case, starting with a declarative contract/IDL and doing something like codegen is a great way to go.

0x696C6961 2 days ago | parent | prev | next [-]

I write all of my openapi specs by hand. It's not hard.

WickyNilliams 2 days ago | parent | next [-]

I imagine you are very much in the minority. A simple hello world is like a screen full of yaml. The equivalent in graphql (or typespec which I always wanted to try as an authoring format for openapi https://typespec.io/) would be a few lines

makeitdouble a day ago | parent | next [-]

I see your point, yet writing openapi specs by hand is pretty common.

There is the part where dealing with another tool isn't much worth it most of the time, and the other side where we're already reading/writing screens of yaml or yaml like docs all the time.

Taking time to properly think about and define an entry point is reasonable enough.

0x696C6961 2 days ago | parent | prev | next [-]

Being verbose doesn't make it difficult.

WickyNilliams 2 days ago | parent [-]

Not necessarily, no. But at a certain point, I believe it does. Difficult to read, is difficult to edit, is difficult to work with.

A sibling comment to your reply expressed the same sentiment as me, and also mentioned typespec as a possible solution

btreecat a day ago | parent | prev [-]

The standard pattern in go and some scala libs, is to define the spec and generate the code.

I think you're over fitting your own experiences.

aitchnyu a day ago | parent | prev [-]

Do you validate responses from client-side and server-side(Fastapi does this and prevents invalid responses from being sent) from spec?

hokkos 2 days ago | parent | prev [-]

I use https://typespec.io to generate openapi, writing openapi yaml quickly became horrible past a few apis.

WickyNilliams 2 days ago | parent [-]

Ha yes, see one of my other comments to another reply.

I never got to use it when I last worked with OpenAPI but it seemed like the antidote to the verbosity. Glad to hear someone had positive experience with it. I'll definitely try it next time I get the chance