swagger-api / swagger-codegen

swagger-codegen contains a template-driven engine to generate documentation, API clients and server stubs in different languages by parsing your OpenAPI / Swagger definition.
http://swagger.io
Apache License 2.0
17k stars 6.03k forks source link

Code/Architecture needs documentation #2104

Open ePaul opened 8 years ago

ePaul commented 8 years ago

As a Java developer trying to contribute some code, I must say that I find it quite hard to orientate myself in the code base.

The README.md has mainly information about the actual usage, and CONTRIBUTING.md has some generic advice.

What I'm missing is a general overview how the code generation (and the configuration) works (the non-language-specific parts). It also doesn't help that most classes and methods don't have any Javadoc, which makes finding out what they are for quite hard.

Could the people who understand how it works please invest some time to write a general overview and Javadocs for the classes in the main package (io.swager.codegen)?


For the current example: I wanted to finally fix #1255 (which I opened myself back in september). I figured out I would add fields modelNamePrefix and modelNameSuffix in DefaultCodeGen, and use them in toModelName (and maybe also toModelFileName?). So far, so easy. The hard part now is figuring out how to get those values into this class from the maven plugin or the CLI.

It looks like some parameters are passed via additionalProperties, others are passed via dedicated setters from outside. To fill additionalProperties from the command line, there is the --additionalProperties option defined in io.swagger.codegen.cmd.Generate, but the Maven-Plugin seems to not support that. Also, CLI seems to use the CodegenConfigurator, which then creates a ClientOptInput, which is passed to a DefaultGenerator. The ClientOptInput contains both a ClientOpts object and a CodegenConfig object, and the additional options are passed from the former into the latter. Though in the CodegenMojo, the additional properties are directly set in the CodegenConfig object (but only some special-cased ones and those which are declared by the CodegenConfig implementation as cliOption and passed to the maven-plugin as configOptions).

Sorry, I can't see any real sense in all this. Can someone help me figure this out? (If someone explains it to me, I can also help to document it, or refactor it so it gets clearer.)

fehguy commented 8 years ago

Hi @ePaul you are correct that the README focuses on usage rather than code structure. There could be a separate development guide for the project which would of course be helpful to a number of people.

The maven plugin is duplicating a lot of work that the codegen proper is doing. The argument parsing and configuration setting should be the same code, but it's not--hence the confusion it's giving you. Note from here:

https://github.com/swagger-api/swagger-codegen/commit/3ddccb5e5cf8ed53f2386070ca8346d11b7fdb8d#diff-728390e70cc7f684e2ecec961cd583ff

Some of the support was added to the CodeGenMojo but it's certainly not complete. If you would like to refactor this to use the argument parsing from Codegen, it'd be greately appreciated.

jimschubert commented 8 years ago

@ePaul It sounds like you've found almost all the right places to put the code. I've only contributed a few things to the csharp/aspnet generators, but I hope I can help you with this.

The CLI uses CodegenConfigurator to aggregate all the options and instantiate the desired language or framework's CodegenConfig. Options for CodegenConfigurator can be preloaded from file a file if you pass the --config/-c option on the CLI.

The DefaultCodeGen class would be the right place to put modelNamePrefix and modelNameSuffix, as far as I can tell. I think the confusion here is that you'd also need to add to the interface CodegenConfig so that CodegenConfigurator can actually interact with the class. I hadn't noticed this before, but most of the generators extend DefaultCodegen and implement CodegenConfig. I would think DefaultCodegen would just implement CodegenConfig, but most of my jvm experience is in Scala so I don't know if there's just some Java-y reason for this.

CodegenConfigurator loads types for generators dynamically via ServiceLoader. To do so, all codegen types need to be registered in src/main/resources/META-INF/services/io.swagger.codegen.CodegenConfig.

To get your options into the DefaultCodegen, you could pass them in as additional properties. To do that, you'd just run swagger-codegen generate with the additional switch -DmodelNamePrefix=Prefix. It'd be cleaner to have it passed in by CLI switch. To do that, you'd want to add a field in Generate.java in the CLI module. The CLI is using airlift/airline for command and option parsing, so you'll need to add an annotation on your field for the CLI.

To get the option into the maven plugin, you'll need to add a field to CodeGenMojo with the maven annotation @Parameter. It looks like CodeGenMojo really should be rewritten to use CodegenConfigurator and just invoke it's toClientOptInput like the CLI does. I think a part of the confusion here is that the CLI's generator was originally written very much the same as the initial commit for the maven plugin. A few months later, someone introduced the CodegenConfigurator to io.swagger.codegen.cmd.Generate but didn't update the maven plugin.

I tried to focus only on CLI and the maven plugin, there's a little more to it when you get into the generators, though.

I hope that helps.

jimschubert commented 8 years ago

I can take a look at refactoring CodeGenMojo to use similar logic to io.swagger.codegen.cmd.Generate.