OpenAPI Generator allows generation of API client libraries (SDK generation), server stubs, documentation and configuration automatically given an OpenAPI Spec (v2, v3)
This is related to discussion in #802 about re-thinking the various TypeScript generators as a single generator that is far more configurable.
Philosophically, I think the new generator should generate as little code as possible via the generator, delegating as much behavior as possible to a runtime that is driven by a "spec metadata" structure. This enables a better developer experience for us creating the generator and makes it easier for plugins to be written that customize the generated API's behavior.
if ({{paramName}} !== undefined) {
{{#isDateTime}}
localVarQueryParameter['{{baseName}}'] = ({{paramName}} as any).toISOString();
{{/isDateTime}}
{{^isDateTime}}
{{#isDate}}
localVarQueryParameter['{{baseName}}'] = ({{paramName}} as any).toISOString();
{{/isDate}}
{{^isDate}}
localVarQueryParameter['{{baseName}}'] = {{paramName}};
{{/isDate}}
{{/isDateTime}}
}
Instead, we should write this as plain TypeScript:
// Assume that generated code has created and passed us a `params` and `paramSpec` object
const {isDateTime, baseName, isDate} = paramSpec;
const paramValue = params[paramName];
if (paramValue !== undefined) {
if(isDateTime) {
localVarQueryParameter[baseName] = paramValue.toISOString();
} else if(isDate) {
localVarQueryParameter[baseName] = paramValue.toISOString();
} else {
localVarQueryParameter[baseName] = paramValue;
}
}
The mustache template's job is now much easier. It can generate something like this:
function fooOperation(param1: string, param2: Date, param3: boolean): Promise<Whatever> {
// Delegate to our runtime, passing it a reference to operation metadata
return invokeOperation({param1, param2, param3}, specMeta.operations.foo); // specMeta is an object containing all the metadata our runtime needs to perform API operations
}
...and then elsewhere, generate the specMeta object: (this code is not perfect but hopefully explains the idea)
interfaces for all models, request bodies, and response bodies
metadata file (JSON or TypeScript object literal)
A few things for which the generator should not generate code:
Parameter validation
Converting parameters into an HTTP request and body
Invoking HTTP requests
All the necessary information should be emitted into a metadata file that is read by runtime libraries to perform the necessary tasks.
In non-JS languages, this might require messy reflection. But in JS, reflection is the norm, and its performance is not unreasonably slow compared to JS code written without reflection. (especially when we consider we're creating an API client that sends HTTP requests, not a compression algorithm)
Writing TS code in mustache templates is inconvenient because we lose the benefits of syntax highlighting and code completion. We can instead write an SDK runtime driven by the metadata emitted by openapi-generator. The metadata object can be strongly typed, so we shouldn't lose safety.
This also makes it a bit more obvious that the runtime can delegate lots of heavy lifting to third-party libraries. For example, schema validation can be implemented as a plugin that uses a third-party validator.
The generator will still be generating function, class, and method signatures for the entire API spec, which is very important to ensure a good developer experience for anyone consuming the generated API client.
EDIT: added an example of mustache template for the spec metadata object.
Description
This is related to discussion in #802 about re-thinking the various TypeScript generators as a single generator that is far more configurable.
Philosophically, I think the new generator should generate as little code as possible via the generator, delegating as much behavior as possible to a runtime that is driven by a "spec metadata" structure. This enables a better developer experience for us creating the generator and makes it easier for plugins to be written that customize the generated API's behavior.
Here's an example:
https://github.com/OpenAPITools/openapi-generator/blob/master/modules/openapi-generator/src/main/resources/typescript-fetch/api.mustache#L165-L177
Instead, we should write this as plain TypeScript:
The mustache template's job is now much easier. It can generate something like this:
...and then elsewhere, generate the specMeta object: (this code is not perfect but hopefully explains the idea)
Things the generator should generate:
A few things for which the generator should not generate code:
All the necessary information should be emitted into a metadata file that is read by runtime libraries to perform the necessary tasks.
In non-JS languages, this might require messy reflection. But in JS, reflection is the norm, and its performance is not unreasonably slow compared to JS code written without reflection. (especially when we consider we're creating an API client that sends HTTP requests, not a compression algorithm)
Writing TS code in mustache templates is inconvenient because we lose the benefits of syntax highlighting and code completion. We can instead write an SDK runtime driven by the metadata emitted by openapi-generator. The metadata object can be strongly typed, so we shouldn't lose safety.
This also makes it a bit more obvious that the runtime can delegate lots of heavy lifting to third-party libraries. For example, schema validation can be implemented as a plugin that uses a third-party validator.
The generator will still be generating function, class, and method signatures for the entire API spec, which is very important to ensure a good developer experience for anyone consuming the generated API client.
EDIT: added an example of mustache template for the spec metadata object.