Duplicate operationId
According to https://github.com/smallrye/smallrye-open-api/issues/1688, it should be resolved, but I am getting also the "SROAP07903: Duplicate operationId"-error.
I have MyResource which makes use of an Interface:
@Path("/myResource")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@ApplicationScoped
public class MyResource implements MyInterface<User>{
@GET
@Path("/{id}")
@APIResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(type = SchemaType.OBJECT, implementation = User.class)))
@Override
public Response getById(Integer id) {
return MyInterfae.super.byId(id);
}
}
The interface:
interface MyInterface<T> {
@GET
@Path("/{id}")
default Response getById(@PathParam("id") Integer id) {
// implemenation
}
}
and the operationId is generated by Quarkus (version 3.15.1) by using the following property:
mp.openapi.extensions.smallrye.operationIdStrategy=CLASS_METHOD
when running in dev or test mode, it prints:
[io.sma.ope.run.sca.spi] (build-9) SROAP07903: Duplicate operationId: MyResource_getById produced by Class: com.acme.MyResource, Method: jakarta.ws.rs.core.Response getById(java.lang.Integer id) and Class: com.acme.MyResource, Method: jakarta.ws.rs.core.Response getById(Integer id)
If I interpret the error message correctly:
It complains about a operationId even though it is the same class (it compares the MyResource class with itself which does not make sense), or?
@nimo23 is the getById method in your interface defined as a default method? Just curious because the code snippet shows a method body.
is the getById method in your interface defined as a default method?
Yes, I corrected it above. It is:
@GET
@Path("/{id}")
default Response getById(@PathParam("id") Integer id) {
// implemenation
}
@nimo23 are you required to re-specify the JAX-RS annotations on the implementation class?
That is, can you remove @GET @Path("/{id}") from MyResource#getById and allow them to be inherited from MyInterface#getById ?
are you required to re-specify the JAX-RS annotations on the implementation class?
Yes, it is required. Since the interface is a generic interface, its implementation can be any class type. For example, the implementation of getId might have different operationIds because they belong to different types of classes:
// within Task implements MyInterface<Task>
@Operation(operationId = "TaskResource_taskById")
or
// within User implements MyInterface<User>
@Operation(operationId = "UserResource_userById")
Therefore, there is no way to set the operationId within the generic class.
What I am getting at is, if you put @GET @Path("/{id}") on getById in the interface, you shouldn't need to have it again in the implementations (as long as there are no other JAX-RS annotations on the implementation methods).
I think in that case you should get the operationIds as expected without the warning in the logs.
What I am getting at is, if you put @GET @Path("/{id}") on getById in the interface, you shouldn't need to have it again in the implementations (as long as there are no other JAX-RS annotations on the implementation methods).
Yes, this seems to solve the problem. However, this problem is only solved as long as the user does not have to override the jax-rs annotations in their implementation class. See https://github.com/jakartaee/rest/blob/main/jaxrs-spec/src/main/asciidoc/chapters/resources/_annotationinheritance.adoc
Fair enough, I'll push a fix for this to ignore duplicates when the duplicate is an override.