OpenAPITools / openapi-generator

OpenAPI Generator allows generation of API client libraries (SDK generation), server stubs, documentation and configuration automatically given an OpenAPI Spec (v2, v3)
https://openapi-generator.tech
Apache License 2.0
21.51k stars 6.51k forks source link

[all-languages] Supporting files duplicated #586

Open Peaches491 opened 6 years ago

Peaches491 commented 6 years ago
Description

Currently, all executions of openapi-generator produce a set of supportingFiles alongside the model/ and api/ files. If you have more than one openapi-generator spec target, these supportingFiles are completely identical, except for the namespace in which they are generated.

This prevents end-users from creating useful libraries or abstractions on top of the generated code, as each generated API uses these supportingFiles objects from different namespaces.

openapi-generator version

All versions.

Steps to reproduce

Generating two separate clients will produce a set of logically conflicting files. With no extra namespace provided, these files will create duplicate symbols when linked together:

openapi-generator generate --input-spec some_api.yaml --generator-name cpp-restsdk --output /tmp/some_api/

openapi-generator generate --input-spec some_other_api.yaml --generator-name cpp-restsdk --output /tmp/some_other_api/

Conflicting supporting files generated in both /tmp/some_api and /tmp/some_other_api/:

├── ApiClient.cpp
├── ApiClient.h
├── ApiConfiguration.cpp
├── ApiConfiguration.h
├── ApiException.cpp
├── ApiException.h
├── CMakeLists.txt
├── HttpContent.cpp
├── HttpContent.h
├── IHttpBody.h
├── JsonBody.cpp
├── JsonBody.h
├── ModelBase.cpp
├── ModelBase.h
├── MultipartFormData.cpp
├── MultipartFormData.h
├── Object.cpp
├── Object.h
├── api
│   └── ...
└── model
    ├── ...
Related issues/PRs

This issue was partially addressed in PR #580, where the cpp-restsdk generator was augmented to take a supportingFilesDirectory and supportingFilesNamespace. That way, a client could be generated with references (i.e. #includes) a set of external supporting files, under the given directory and the given namespace.

Suggest a fix/enhancement

Unfortunately, the solution in #580 is not a complete solution. A complete solution would require the following:

[ ] A way for users to (optionally) generate only supporting files, using a specified namespace [ ] A parameter to client generation which prevents the creation of supporting files if an external set of supporting files is specified.

rienafairefr commented 6 years ago

Yeah, it's a concern that I think is linked to what I've partially expressed and implemented in the Python target (see #470). The idea that sometimes the users (the one generating the SDK) have different a priori about the directory structure of the generated code. The idea that sometimes we want to generate a package, namespaced code in your C++ case, and not generate duplicated supporting files that don't depend on the spec

I was interested in this issue so I've created this: https://gist.github.com/rienafairefr/4224a9ff03cd0154f1ea7ff5e680ba59

I'm running the generator on all the known generators, with two different APIs (petstore and wordnik included in the test resources), with the same package name and the same info (because the description of the api is used in a bunch of places, usually in comments so I had to normalize these), and comparing the resulting file hierarchy. This way I can see which files are generated that don't depend on the spec at all.

As you've identified, cpp-restsdk is a good example of that behavior, where a large bunch of files are generated identically no matter the spec. I would call these "common files"

There are two kind of common files though, some that are code, some that are not, and I guess we can't bunch them together blindly. And the solution to generate files that are common to all openapi-generator targets is very language dependent. I'm not sure we can find a generic solution for all languages

demonfiddler commented 6 years ago

By way of agreement, @rienafairefr, yes, different generators treat supporting files differently and in addition, supporting files from multiple generator invocations are not necessarily identical. Supporting files can contain references to api and model packages, which makes them non-interchangeable. This presents a particular problem if the generator always puts them in the same place. If you want multiple code generator executions against different spec files within the same project to generate a combined codebase, such package-sensitive supporting files end up either overwriting previously generated files or blocking generation of subsequent files.

I think that at the generic level the best we might hope for is a finer-grained control over which supporting files get generated and where they end up with respect to api and model files. As things currently stand, some code generators give little thought to multi-spec, multi-execution generation scenarios, which makes such use cases hard to implement, requiring the build system to compensate for the limited generator configurability.