Spin off the generator as its own project
Description
Hello, I just want to say I really appreciate this project. I've been using it for schema first API design and I look forward to the tanstack query support. I have also been using this (modified) project to generate types for Fastify handlers (example below). This has enabled me to safely handle request parameters and response types. This in conjunction with a Fastify plugin for schema validation has lead to a great developer experience. In short, I can generate clients and server types from API spec.
I was wondering if it was possible to spin off the generator as its own project so that other projects that wanted to generate code from OpenAPI spec could do. I know there has been trouble accommodating all json schema types conversion to TS and it would be nice to have that dealt with in a united project. Thanks!
// generated code
import {type RouteHander} from "fastify";
type Handlers = {
createUser: RouteHandler<{
Body: NewUser;
Reply: {
201: User;
400: Error;
401: Error;
409: Error;
500: unknown;
};
}>;
getUser: RouteHander<{
Reply: {
200: User;
400: Error;
401: Error;
500: unknown;
};
}>;
};
// implement handlers
const handlers: Handlers = {
createUser: async function (request, reply) {}
getUser: async function (request, reply) {}
}
fastify.register(glue, {
specification: "api.yaml",
serviceHandlers: handlers,
prefix: "v1",
});
Hey @jcx0, would your initial use case be to replace your modified project to handle Fastify codegen? Do you have a link to your modified project?
Yes I would hope the generator could be used as a dependency for the Fastify codegen for others to use. My project is an older openapi-ts build, most of the changes were to the types codegen https://github.com/jcx0/fastify-ts/commit/7647f46e91792f7f9f4d342a3c2bc6a485b253d7. It reuses the generated types and uses operation id instead of path/http method to map to the request/reply parameters.
The good news is that's on the roadmap. The bad news is, not anytime soon. If this issue gains more interest, it could get prioritised
Understandable! This would require a good deal of refactoring and I see there is a lot of work being done. Thank you for your replies
@jcx0 Are you able to roughly list what changes you've made in your repository? Think it would be easier to get this working well for you first rather than try to create a generic solution for potential users (who may or may not come)
Most of my changes were to the types generator. The changes were:
- Use operation id instead of paths to map types
- Reshape the operation parameters to match Fastify generic types
openapi-ts:
path: { method: { req: { body: {}, query: {}, header: {}, path: {} } res: { 200: {} } } }fastify:operationId: { Body: {}, Querystring: {}, Params: {}, Headers: {}, Reply: { 200: {}} } - Wrap the operations parameters with the Fastify RouteHandler type
The reason why I used this project's generator because the output is 99% close enough to what I need for types for Fastify. In fact with the current output I could use some TS utility type magic to get what I want. The only thing I would like is an operation id to path map such as below. The biggest feature wanted from the generic solution would be the JSON Schema to TS type conversion given an OpenAPI spec which the types generator deals with nicely.
I also see no need for a generic solution if there isn't much interest from other users. Perhaps I could do a better job of showing this off--I am new to the open source community. I do believe this helps the DX for schema first design and would help adoption.
export type $OpenApiTs = {
"/user": {
post: { req: CreateUserData, res: { 200: User } }
get: { res: { 200: User } }
}
};
export type Operations = {
createUser: $OpenApiTs["/user"][post];
getUser: $OpenApiTs["/user"][get];
}
Examples definitely help. How does Fastify handle responses with multiple content types?
Fastify natively only handles text/plain and application/json to remain lightweight. Additionally support is through plugins and custom parsers.
https://fastify.dev/docs/latest/Reference/ContentTypeParser/
Another Fastify user https://github.com/hey-api/openapi-ts/issues/876#issuecomment-2274326589
I can dedicate time to help now if it's wanted, but I can understand if other features are a priority right now (I can see there is active development of an experimental parser and this would delay that and other features).
As for implementation: we could create a generator directory in package/openapi-ts and do an incremental migration starting with openApi, moving on to the compiler, and then exposing the smaller, commonly used helper functions in generate. Once extracting all the common code, we could then move it into its own package openapi-generator(?).
Instead of picking out fields from UserConfig/ClientConfig to define Config we could do a copy/paste of the required subset of fields and pass the values from UserConfig/ClientConfig to Config when we call the functions in generator.
Any concerns on this approach? Again, more than happy to help/experiment and wouldn't be mad if it ends up being shelved.