I think for me it comes down to a few key points:
- APIs are forever, the choice of language/framework is an implementation detail
- Constraining yourself to what can be represented in the specification is better than generating a specification from implementation that may not be capable of expressing the full details
- When working with diverse languages it provides a common ground/language for discussing API changes. Eg: if you have java backend, kotlin android, swift iOS, react/whatever web you can bring everyone together with the spec
- Subjective, but a good spec will include a bunch of documentation and examples that tend to create a lot of noise in the code. I personally prefer to keep this in the spec and the implementation smaller
I think the main counterpoint to this is that you can generate the spec and then take that and change your mind if you later change language/framework etc - it's not a one-way door.
My biggest bug bear is that regardless of spec first or implementation first, you should have something you write once and generate the rest of the glue from (eg: docs, client sdks). Writing each piece manually/independently always leads to drift and bugs.
(I'm working on my own little openapi -> typescript code generator over here https://github.com/mnahkies/openapi-code-generator - eventually plan to support more than typescript, and adding typespec support is something I'm currently considering)