Issue when generating Java client for Jira Cloud from OpenAPI specs

Hi everyone! :wave:

We’re trying to generate a Java client to interact with the Jira Cloud REST API v3 using OpenAPI generator and the provided OpenAPI specifications.

However, we’re having a bit of trouble and were wondering if anyone else had encountered the same issues?

We are using the java generator and the resttemplate library.
Here’s the configuration we use for the OpenAPI generator Maven plugin:

Maven configuration
<!-- OpenAPI generator plugin -->
<plugin>
    <groupId>org.openapitools</groupId>
    <artifactId>openapi-generator-maven-plugin</artifactId>
    <version>${openapi-generator-maven-plugin.version}</version>
    <executions>
        <!-- Jira Rest API v3 -->
        <execution>
            <id>jira</id>
            <goals>
                <goal>generate</goal>
            </goals>
            <configuration>
                <inputSpec>${project.basedir}/src/main/resources/jira/openapi-jira-v3.v3.json</inputSpec>
                <!-- Generate a Java client -->
                <generatorName>java</generatorName>

                <!-- Configure the output -->
                <output>${project.build.directory}/generated-sources</output>
                <apiPackage>${jira.package}.v3</apiPackage>
                <modelPackage>${jira.package}.v3.model</modelPackage>
                <invokerPackage>${jira.package}.v3.client</invokerPackage>

                <!-- Configure the generated code -->
                <generateApis>true</generateApis>
                <generateModels>true</generateModels>
                <generateSupportingFiles>true</generateSupportingFiles>
                <generateModelTests>false</generateModelTests>
                <generateApiTests>false</generateApiTests>
                <generateModelDocumentation>true</generateModelDocumentation>
                <generateApiDocumentation>true</generateApiDocumentation>

                <!-- Fix ambiguous imports -->
                <importMappings>
                    <importMapping>Locale=java.util.Locale</importMapping>
                </importMappings>

                <configOptions>
                    <!-- Generate code for the RestTemplate -->
                    <library>resttemplate</library>

                    <!-- Generate code for Spring Boot 3 -->
                    <useSpringBoot3>true</useSpringBoot3>

                    <!-- Use jakarta.* instead of java.* imports -->
                    <useJakartaEe>true</useJakartaEe>

                    <!-- Disable documentation annotations -->
                    <annotationLibrary>none</annotationLibrary>

                    <!-- Disable OpenAPI documentation -->
                    <documentationProvider>none</documentationProvider>

                    <!-- Disable OpenAPI Jackson nullable library -->
                    <openApiNullable>false</openApiNullable>
                </configOptions>
            </configuration>
        </execution>

    </executions>
</plugin>

First, we had an issue due to an ambiguous import of Locale.
We managed to fix this using an import mapping to force the use of java.util.Locale.

Then, we had an issue with the WorkflowCapabilities schema.
Indeed, OpenAPI generator seems to get confused and handles the projectTypes property as both an enum and an array:

Generated code
public class WorkflowCapabilities {
  // [...]
  
  private ProjectTypesEnum projectTypes;
  
  // [...]

  public WorkflowCapabilities addProjectTypesItem(ProjectTypesEnum projectTypesItem) {
    if (this.projectTypes == null) {
      this.projectTypes = new ArrayList<>();
    }
    this.projectTypes.add(projectTypesItem);
    return this;
  }
  
  // [...]
}

We though this might be a bug in the OpenAPI generator.
However, by checking the OpenAPI specifications, we found that the projectTypes property of the WorkflowCapabilities schema was indeed a bit ambiguous.
Indeed, the projectTypes property is declared as an array of enum but also contains an enum attribute which leads the OpenAPI generator to think this property is both an array and an enum:

OpenAPI specifications
"WorkflowCapabilities": {
  "additionalProperties": false,
  "properties": {
    // [...]
    "projectTypes": {
      "description": "The types of projects that this capability set is available for.",
      "enum": [
        "software",
        "service_desk",
        "product_discovery",
        "business",
        "unknown"
      ],
      "items": {
        "description": "The types of projects that this capability set is available for.",
        "enum": [
          "software",
          "service_desk",
          "product_discovery",
          "business",
          "unknown"
        ],
        "type": "string"
      },
      "type": "array"
    },
    // [...]
  },
  "type": "object"
},

For now, we managed to generate the Java client by manually updating the OpenAPI specifications and removing the enum attribute of the projectType property in the WorkflowCapabilities schema.
However, this is of course not great for maintainability.
We are considering contributing to OpenAPI generator to ignore the enum attribute if the type of a property is array or using a different OpenAPI generator library (but we need to use RestTemplate).

What are your thoughts on the subject?
Do you have other solutions?
Do you think it is a bug in the OpenAPI generator library?
Do you think the OpenAPI specifications for the Jira Cloud REST API v3 should be updated? :wink:

Cheers!

1 Like

@JoaoBrltYogi,

I’ve experimented a lot with Jira’s OpenAPI Spec, leaving me with the following opinions:

Yes. For Java, Retrofit. Because it seems like bad architecture to bind to the entire API surface when you only use a part.

Yes and no. More precisely, I think general purpose libraries must make decisions about how to best support a range of APIs. I think it would be reasonable to expect to invest in customization for an API like Jira’s with so much history. To the extent that it might be preferable to have a Jira-specific generator. For example, I’d think any reasonable app would need to handle:

  • Pagination: Jira isn’t exactly consistent across endpoints)
  • Rate limiting: Jira doesn’t have fixed limits but headers to watch.
  • Errors: There are cases where Jira returns errors in a 200 response. :frowning:

Yes and no. More precisely, I know there are worse errors in Jira’s API spec. Again, with Jira’s long history, I think there are going to be some parts of the API that don’t fit neatly into OpenAPI Spec. There is going to be some “impedance mismatch”.

I don’t want to discourage your use of OpenAPI generation. That’s going to be a better approach than a hand-crafted SDK. But, I do want to point out some of the trickier bits for your awareness. Jira’s OpenAPI does not mean you can get an SDK without effort.

2 Likes

First, we had an issue due to an ambiguous import of Locale .

@JoaoBrltYogi I think this is normal. I recall having used modelNamePrefix or modelNameSuffix to work around it for other APIs. But we could potentially rename that schema if you think it’s a big problem.

the projectTypes property is declared as an array of enum but also contains an enum attribute which leads the OpenAPI generator to think this property is both an array and an enum

This seems like a bug in our spec. Could you please raise an issue for it? I don’t think it’s a case OpenAPI generator needs to handle.

2 Likes

Hi @ibuchanan!

Yes. For Java, Retrofit . Because it seems like bad architecture to bind to the entire API surface when you only use a part.

We didn’t know Retrofit, thanks for the suggestion. :ok_hand:

Yes and no. More precisely, I think general purpose libraries must make decisions about how to best support a range of APIs. I think it would be reasonable to expect to invest in customization for an API like Jira’s with so much history. To the extent that it might be preferable to have a Jira-specific generator.

Indeed, we haven’t used the generated client enough to identify these issues yet.
Thanks for raising awareness about these consistency issues, etc.

Yes and no. More precisely, I know there are worse errors in Jira’s API spec. Again, with Jira’s long history, I think there are going to be some parts of the API that don’t fit neatly into OpenAPI Spec. There is going to be some “impedance mismatch”.

Yes, I feel like it’s normal for such a large REST API with several teams working on it.
Indeed, this means our solution will probably need a lot of refinement to make sure we properly handle each request to the Jira REST API.
To be honest, we were hoping to find an existing Java client in the wild but sadly it does not seem to be the case.

Hi @epehrson!

Thanks for the quick response.

I think this is normal. I recall having used modelNamePrefix or modelNameSuffix to work around it for other APIs. But we could potentially rename that schema if you think it’s a big problem.

Yes, no problem for naming conflicts.
They are pretty easy to fix using the configuration parameters of the OpenAPI generator. :ok_hand:

This seems like a bug in our spec. Could you please raise an issue for it? I don’t think it’s a case OpenAPI generator needs to handle.

Thanks for the suggestion.
We just raised an issue with detailed information on the subject (ECOHELP-38089). :crossed_fingers:

1 Like

I have created below bug ticket to have this fixed:

Anyone interested can set themselves as watchers so that they will be notified in case of any update/progress.

Cheers,
Dario

1 Like