4

I can not find out why my rest api endpoints are not visible / executable in openapi/ui with openliberty. openapi/ui reports "there are no operations defined in spec!" My project consists of an empty application class and a trivial rest controller with a single endpoint:

package sandbox.io.rest;

import jakarta.ws.rs.ApplicationPath;
import jakarta.ws.rs.core.Application;

@ApplicationPath("/api")
public class RestApplication extends Application { }
package sandbox.io.rest;

import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON;

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.Response;

@ApplicationScoped
public class RestController
{
    @GET
    @Path("/system/properties")
    @Produces(APPLICATION_JSON)
    public Response getSystemProperties()
    {
        return Response.ok(System.getProperties()).build();
    }
}

I have the following features activated in my server.xml:

    <featureManager>
        <feature>jakartaee-9.1</feature>
        <feature>microProfile-5.0</feature>
<!--        <feature>restfulWS-3.0</feature> -->
<!--        <feature>jsonp-2.0</feature> -->
<!--        <feature>jsonb-2.0</feature> -->
<!--        <feature>cdi-3.0</feature> -->
<!--        <feature>mpConfig-3.0</feature> -->
<!--        <feature>mpRestClient-3.0</feature> -->
<!--        <feature>mpOpenAPI-3.0</feature> -->
    </featureManager>

Everything was generated from openliberty/get started.

There is a real minimal reproducer here.

I also played around with activation of mpOpenAPI-3.0 feature but could not make it work. Could anybody have a look at the reproducer please?

BTW: Please don't get irritated by the repo name, it's just that I try to set up an environment for openliberty, hibernate and postgres ... However I'd like to use openapi/ui, too.

r-uu
  • 423
  • 1
  • 4
  • 18

2 Answers2

10

In addition to Scott Kurz's answer: https://stackoverflow.com/a/71946440/8067386

The reason OpenAPI isn't finding the endpoint is because without the @PATH annotation (or @Provider) your RestController class is not being registered with the JAX-RS runtime. An older way to register would be to return RestController.class from RestApplication.getClasses(). However, this is less dynamic than annotating your endpoint class.

atanders
  • 101
  • 4
5

You can fix this by adding a class-level @Path annotation. To keep the aggregate URL path the same you can do @Path("/") so:

@Path("/")
@ApplicationScoped
public class RestController
{
    @GET
    @Path("/system/properties")
    @Produces(APPLICATION_JSON)
    public Response getSystemProperties()
    {
        return Response.ok(System.getProperties()).build();
    }
}

I believe this is more a Jakarta RESTful issue than an MicroProfile OpenAPI issue as it turns out.

Scott Kurz
  • 4,985
  • 1
  • 18
  • 40
  • Yes, for now that did it! Please tell me, is there any way that I could have found out this by myself? – r-uu Apr 20 '22 at 22:13
  • 1
    Good question. One answer, from an Open Liberty perspective, is to look to our guides (https://openliberty.io/guides/) as a good place to find working code to model after. E.g. the Open API guide: https://openliberty.io/guides/microprofile-openapi.html shows an example that made me realize this was your issue. – Scott Kurz Apr 21 '22 at 01:34
  • I tried hard to compare my simple approach with the guide you mentioned but I obviously missed that difference. However, I can confirm that it works with a class level ´´´@Path´´´ annotation and it fails without one. As far as I know a class level ´´´@Path´´´ annotation is not mandatory in Jakarta REST, is it? – r-uu Apr 21 '22 at 10:37
  • 1
    A class level `@Provider` annotation is required to register your resource class with the JAX-RS runtime if you aren't registering it manually via the `Application.getClasses()` method. `@Path` will function as an `@Provider` annotation. – atanders Apr 21 '22 at 14:38