OpenAPI Code Generator

The OpenAPI code generator makes client libraries from a swagger API. You can find it here:

https://github.com/OpenAPITools/openapi-generator

It’s fairly easy to run. In my case I’m trying to generate go:

java -jar openapi-generator-cli.jar generate -i tulip_api.json -g go -o out --skip-operation-example --skip-validate-spec --verbose

The input file is https://YOUR_HOST.tulip.co/docs/api/api.json

The problem is, there’s something about tulip_api.json that it doesn’t like, and I can’t figure out what it is:

[main] INFO  o.o.codegen.TemplateManager - writing file /mnt/c/work/go/tulip-mqtt/crap/out/api_machine_monitoring.go
[main] INFO  o.o.codegen.TemplateManager - writing file /mnt/c/work/go/tulip-mqtt/crap/out/docs/MachineMonitoringApi.md
[main] INFO  o.o.codegen.TemplateManager - writing file /mnt/c/work/go/tulip-mqtt/crap/out/api_misc.go
[main] INFO  o.o.codegen.TemplateManager - writing file /mnt/c/work/go/tulip-mqtt/crap/out/docs/MiscApi.md
[main] INFO  o.o.codegen.TemplateManager - writing file /mnt/c/work/go/tulip-mqtt/crap/out/api_tulip_apps.go
[main] INFO  o.o.codegen.TemplateManager - writing file /mnt/c/work/go/tulip-mqtt/crap/out/docs/TulipAppsApi.md
[main] INFO  o.o.codegen.TemplateManager - writing file /mnt/c/work/go/tulip-mqtt/crap/out/api_tulip_machines.go
[main] INFO  o.o.codegen.TemplateManager - writing file /mnt/c/work/go/tulip-mqtt/crap/out/docs/TulipMachinesApi.md
Exception in thread "main" java.lang.RuntimeException: Could not generate api file for 'TulipTables'
        at org.openapitools.codegen.DefaultGenerator.generateApis(DefaultGenerator.java:665)
        at org.openapitools.codegen.DefaultGenerator.generate(DefaultGenerator.java:891)
        at org.openapitools.codegen.cmd.Generate.execute(Generate.java:441)
        at org.openapitools.codegen.cmd.OpenApiGeneratorCommand.run(OpenApiGeneratorCommand.java:32)
        at org.openapitools.codegen.OpenAPIGenerator.main(OpenAPIGenerator.java:66)
Caused by: java.lang.NullPointerException
        at org.openapitools.codegen.languages.GoClientCodegen.constructExampleCode(GoClientCodegen.java:541)
        at org.openapitools.codegen.languages.GoClientCodegen.constructExampleCode(GoClientCodegen.java:492)
        at org.openapitools.codegen.languages.GoClientCodegen.postProcessOperationsWithModels(GoClientCodegen.java:460)
        at org.openapitools.codegen.DefaultGenerator.processOperations(DefaultGenerator.java:1212)
        at org.openapitools.codegen.DefaultGenerator.generateApis(DefaultGenerator.java:568)

I’m not sure where the problem is, but there’s something about the ‘tables’ api description in the swagger file that it doesn’t like. It generates the object models OK but when it generates the API modules it creates api_misc.go, api_machine_monitoring.go, api_tulip_machines.go, api_tulip_apps.go, then tries to generate tables and it fails. There must be something different about the way the tables API is defined in the swagger.

I tried separately generating ONLY the documentation (in markdown) and that process worked without errors. So the problem seems to be in the code generation itself.

A big part of the point of using swagger is code generation, and this particular generator is fairly widely used. I use it to generate go and java clients all the time.

The code generator does generate some warnings, but I don’t think they’re really related. I’m not fluent enough with OpenAPI 3 to know if these are actual problems:

[main] WARN  o.o.codegen.DefaultCodegen - allOf with multiple schemas defined. Using only the first one: AnyType
[main] WARN  o.o.codegen.DefaultCodegen - allOf with multiple schemas defined. Using only the first one: ApiError
[main] WARN  o.o.codegen.DefaultCodegen - allOf with multiple schemas defined. Using only the first one: CRUDModel
[main] WARN  o.o.codegen.DefaultCodegen - Empty operationId found for path: get /tables/{tableId}/runAggregation. Renamed to auto-generated operationId: tablesTableIdRunAggregationGet
[main] WARN  o.o.codegen.DefaultCodegen - Empty operationId found for path: patch /tables/{tableId}/records/{recordId}/increment. Renamed to auto-generated operationId: tablesTableIdRecordsRecordIdIncrementPatch
[main] WARN  o.o.codegen.DefaultCodegen - Empty operationId found for path: post /attributes/report. Renamed to auto-generated operationId: attributesReportPost
[main] WARN  o.o.codegen.DefaultCodegen - More than one inline schema specified in allOf:. Only the first one is recognized. All others are ignored.
[main] WARN  o.o.codegen.utils.ModelUtils - #/components/parameters/tableFilterAggregator is not defined

Any ideas?

Hi Christopher, glad you’re making use of our OpenAPI documentation!

That NullPointerException doesn’t have a lot of context to indicate what is wrong. I tried checking our documentation in the Swagger Editor and noticed some warnings related to the :linkId path parameter using the incorrect format. I wonder if those are fixed if it will fix the issue the generator is running into.
Could you try replacing the text :linkId with {linkId} everywhere it appears in the API paths and update the name field of components/parameters/tableLinkId to be linkId instead of tableLinkId and let me know if that resolves the issue?

I’m not sure what those other warnings are about. Particularly the last one is confusing because I see tableFilterAggregator under in the components/parameters section in the documentation.

Sure thing, I will give it a try when I get home

OK, done, but that didn’t fix/change the results. I think what I’d like to do is to post this as an issue on the openapi codegen github, but I’m not sure which version to switch. In particular, the :linkId → {linkId} seems right - or at least, makes it consistent with the rest of the document. I’m afraid I might have gone too far, though - do you want all tableLinkId to be renamed? That’s actually what I did.

For tableLinkId, I was referring to changing only the name field of the definition under components/parameters/tableLinkId.

Still, I’m not sure this will actually fix the issue with the codegen tool. I think opening an issue on their GitHub to at least get more information about what could be causing the NullPointerException would be good.

For me to open an issue with them, they are going to want access to your OpenAPI json spec. I’m not sure how to add that to the ticket legally - it’s not clear to me that I can just copy it into the ticket without infringing on a Tulip copyright, and I can’t share the link that I have to the API documentation because it includes my customer name as part of the URL. Can you enlighten me as to the terms and conditions of the API? If it’s truly ‘public’ I can just copy it into the ticket, but in many cases these APIs are licensed for use only by customers, not allowed to be reshared with the general public.

If you can point me to some license.txt file that says this is OK, I’ll go ahead and write an OpenAPI issue. Otherwise, I’m thinking it would be better if a Tulip employee did it…

I apologize for the lack of license on our documentation, that’s something we’re working on. In the mean time, I checked with my team and can give you written permission to post the API in the ticket. If you want to redact your customer name from the documentation that would be fine.

No problem!

OK. I will write a ticket on this. It’s probably going to be a few days until I can do it, but I’ll update you here. My last attempts are that you can generate a client for Tulip (using your OpenAPI spec) for Java or Python no problem, it’s only the Go version that blows up. It’s POSSIBLE that it’s a problem that’s specific to the Go generator, but at this point I’m not convinced - I think it’s just as likely there’s something about the .json that is not quite right, and the other generators just aren’t as picky about it.

One of the great things about OpenAPI is using swagger to produce fairly decent documentation, and you have succeeded (A+) on that front. The other advantage is being able to dynamically build a client for nearly every programming language and methodology. I’m working a lot in Go these days so I’d really like this to work. Thank you for working with me!

–Chris

Sounds good! Please let us know if you discover that the problem is with our documentation so we can fix it. Glad to hear it’s working well for you otherwise. I agree that the concept of OpenAPI and all the associated tools for documentation and code generation are very useful, and we’d like to enable customers to use these with Tulip as much as possible.