I'm trying to generate a API documentation/swagger client for a Java EE application using Swagger / OpenAPI 3.0, but one method keeps missing in the documentation. I created a sample project to clarify my problem:
New, less complex example:
I got an Interface with a List as a parameter for my REST endpoint:
package de.rockbunker.api;
import javax.ws.rs.core.Response;
import java.util.List;
public interface Pong<T> {
Response pongList(List<T> pongs);
}
I'll implement this service and add swagger annotations:
package de.rockbunker.api;
import io.swagger.v3.oas.annotations.Operation;
import javax.enterprise.context.ApplicationScoped;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.core.Response;
import java.util.List;
@ApplicationScoped
@Path("")
public class PingService implements Pong<String> {
// Does not show up in documentation!?
@POST
@Path("pongList")
@Operation(summary = "Pong List in Interface", tags = "Pong")
@Override
public Response pongList(List<String> pongs) {
return Response.ok().build();
}
}
I try to generate a openapi documentation using the maven plugin (full configuration see below):
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-maven-plugin</artifactId>
<version>2.1.1</version>
But the generated documentation remains empty, the endpoint does not show up:
openapi: 3.0.1
More complex example
My rest endpoint implements a interface with a type parameter. I tried to use this parameter in several ways, resulting in this interface
public interface Pong<T> {
Response pongList(List<T> pongs);
Response pongArray(T[] pongs);
Response justPong(T pong);
Response pongNoTypeParameter(List<Integer> intPongs);
}
The service that implements the interface looks like this:
package de.rockbunker.api;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Schema;
import javax.enterprise.context.ApplicationScoped;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.core.Response;
import java.util.List;
@ApplicationScoped
@Path("")
public class PingService implements Pong<String>{
// Works
@GET
@Path("ping")
@Operation(summary = "Just ping", tags = "Ping")
public Response ping() {
return Response.ok("Ping").build();
}
// Does not show up
@POST
@Path("pongListInInterface")
@Operation(summary = "Pong List in Interface", tags = "Pong")
@Override
public Response pongList(List<String> pongs) {
return Response.ok().build();
}
// Works
@POST
@Path("pongArrayInInterface")
@Operation(summary = "Pong Array in Interface", tags = "Pong")
@Override
public Response pongArray(String[] pongs) {
return Response.ok().build();
}
// Works
@GET
@Path("pong")
@Operation(summary = "Just pong", tags = "Pong")
@Override
public Response justPong(String pong) {
return Response.ok().build();
}
// Works
@GET
@Path("intPong")
@Operation(summary = "Just Integer pongs", tags = "Pong")
@Override
public Response pongNoTypeParameter(List<Integer> intPongs) {
return Response.ok().build();
}
// Works
@POST
@Path("pongListNoInterface")
@Operation(summary = "Pong List no Interface", tags = "Pong")
public Response pongListNoInterface(List<String> pongs) {
return Response.ok().build();
}
}
The openapi docmentation is generated, using the Maven plugin io.swagger.core.v3.swagger-annotations in version 2.1.1, resulting in a documentation that contains every method, but Response pongList(List<T> pongs); Every other use of that type parameter somehow works nicely, only when I use the type parameter as the type of a list I can't get it to show up.
openapi: 3.0.1
paths:
/pong:
get:
tags:
- Pong
summary: Just pong
operationId: justPong
requestBody:
content:
'*/*':
schema:
type: string
responses:
default:
description: default response
content:
'*/*': {}
/pongArrayInInterface:
post:
tags:
- Pong
summary: Pong Array in Interface
operationId: pongArray
requestBody:
content:
'*/*':
schema:
type: array
items:
type: string
responses:
default:
description: default response
content:
'*/*': {}
/ping:
get:
tags:
- Ping
summary: Just ping
operationId: ping
responses:
default:
description: default response
content:
'*/*': {}
/intPong:
get:
tags:
- Pong
summary: Just Integer pongs
operationId: pongNoTypeParameter
requestBody:
content:
'*/*':
schema:
type: array
items:
type: integer
format: int32
responses:
default:
description: default response
content:
'*/*': {}
/pongListNoInterface:
post:
tags:
- Pong
summary: Pong List no Interface
operationId: pongListNoInterface
requestBody:
content:
'*/*':
schema:
type: array
items:
type: string
responses:
default:
description: default response
content:
'*/*': {}
Plugin configuration:
<plugin>
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-maven-plugin</artifactId>
<version>2.1.1</version>
<configuration>
<outputFileName>openapi</outputFileName>
<outputPath>${project.build.directory}/${project.artifactId}-${project.version}</outputPath>
<outputFormat>JSONANDYAML</outputFormat>
<resourcePackages>
<package>de.rockbunker.api</package>
</resourcePackages>
<prettyPrint>true</prettyPrint>
</configuration>
<executions>
<execution>
<phase>compile</phase>
<goals>
<goal>resolve</goal>
</goals>
</execution>
</executions>
</plugin>
Complete pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>de.rock-bunker</groupId>
<artifactId>swagger-ui-test</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>8.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-client</artifactId>
<version>4.3.1.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.jboss.resteasy/resteasy-jackson2-provider -->
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jackson2-provider</artifactId>
<version>4.3.1.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.swagger.core.v3/swagger-jaxrs2 -->
<!-- <dependency>-->
<!-- <groupId>io.swagger.core.v3</groupId>-->
<!-- <artifactId>swagger-jaxrs2</artifactId>-->
<!-- <version>2.1.1</version>-->
<!-- </dependency>-->
<dependency>
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-annotations</artifactId>
<version>2.1.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.3</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>11</source>
<target>11</target>
</configuration>
</plugin>
<plugin>
<groupId>com.googlecode.maven-download-plugin</groupId>
<artifactId>download-maven-plugin</artifactId>
<version>1.2.1</version>
<executions>
<execution>
<id>swagger-ui</id>
<goals>
<goal>wget</goal>
</goals>
<configuration>
<url>https://github.com/swagger-api/swagger-ui/archive/master.tar.gz</url>
<unpack>true</unpack>
<outputDirectory>${project.build.directory}</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>copy-resources</id>
<phase>validate</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>target/${project.artifactId}-${project.version}</outputDirectory>
<resources>
<resource>
<directory>${project.build.directory}/swagger-ui-master/dist</directory>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-maven-plugin</artifactId>
<version>2.1.1</version>
<configuration>
<outputFileName>openapi</outputFileName>
<outputPath>${project.build.directory}/${project.artifactId}-${project.version}</outputPath>
<outputFormat>JSONANDYAML</outputFormat>
<resourcePackages>
<package>de.rockbunker.api</package>
</resourcePackages>
<prettyPrint>true</prettyPrint>
</configuration>
<executions>
<execution>
<phase>compile</phase>
<goals>
<goal>resolve</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
I dont quite get it. Why is the method Response pongList(List<T> pongs); missing in the documentation? Maybe you can tell me :-).
Greetings!
this feels like a bug to me. As a work-around you could just wrap your list into another object, without any type parameter it should work.
Greetings
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With