I generally prefer code generation. I don't see why it is "error prone" any more than anything else is. In fact, it means that errors aren't concealed in two levels of abstraction which can make them much harder to debug. Also, with generated code, you can add a build step to work around short comings or bugs in the generator where as you otherwise have no choice to live with it.
The "annoying" part I do get -- it's obviously nicer to have instant feedback than being forced to rebuild things -- so for things where you iterate a lot, that does weigh in the other direction.
+1. It even looks very similar to TypeScript. Why not use TypeScript as a description of APIs in the first place? Get TypeScript types and even generate OpenAPI schema on the fly to serve it at `/openapi`?
Typescript is too powerful, there are a lot of typescript constructs that can't be represented in OpenAPI specs. Or that could generate massively complex OpenAPI specs that would bring your tooling performance to a crawl.
A subset of typescript could work, but I imagine it would be fairly confusing to support some features here and other features there.
I think they are going for a minimum common denominator approach and eventually add other targets besides OpenAPI.
The solutions you are talking about are called "code-first", TypeSpec is a "schema-first" solution. Both solutions have their pros and cons:
Code-first:
- No extra steps between code and running application
- No mismatch between schema and code
- Requires tooling for every language used in your stack. This tooling is usually more complex than schema-first codegen, but it is almost always built-into and core of the backend framework you are using so it tends to be better supported.
- Requires teams to know each service's backend language to propose changes
- Harder to build a coherent central API documentation if you have multiple services. Requires complex tooling for merging the different schemas from the different services
Schema first:
- Schema first means contract-first design, scales better to products with multiple separate teams using multiple languages. It is easier to learn the schema DSL than poke around backend language unknown to the developer
- Any change in the contract requires changes in two places (schema and code)
- API consumers can easily suggest changes to the schema that are implemented by the relevant team
- Usually requires some codegen step for each backend and client languages (with the usual codegen problems). Runtime-only schema validation can be done but it is usually a bad idea to rely only on it.
- Easier mocking. Clients can start implementing before backend is ready, tests can be written against mocks.
There are definitely more pros and cons that I am missing, but it is a tradeoff. I would say if you have multiple backend services and supporting multiple backend languages I would definitely go for schema-first.
You can work with OpenAPI in a schema-first way but as many people have pointed out over the years OpenAPI yaml files are, to be polite, not very human-friendly. TypeSpec seems to be a more sensible way to work with HTTP apis in a schema first way while keep interoperability with existing OpenAPI tooling at the cost of extra codegen step (typespec .tps -> openapi .yaml)
The "annoying" part I do get -- it's obviously nicer to have instant feedback than being forced to rebuild things -- so for things where you iterate a lot, that does weigh in the other direction.