question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Problem with OpenAPI plugin (Java+Annotations)

See original GitHub issue

I tried to use kotlin-openapi3-dsl plugin with Javalin according to this documentation: https://javalin.io/plugins/openapi

In my sample class here: https://github.com/pwittchen/money-transfer-api/blob/master/src/main/java/com/pwittchen/money/transfer/api/controller/AccountController.java

I added annotations as follows:

public class AccountController {

  private ContextWrapper contextWrapper;
  private AccountRepository accountRepository;

  @Inject
  public AccountController(
      final ContextWrapper contextWrapper,
      final AccountRepository accountRepository) {
    this.contextWrapper = contextWrapper;
    this.accountRepository = accountRepository;
  }

  @OpenApi(
      method = HttpMethod.GET,
      path = "/account",
      pathParams = @OpenApiParam(name = "id", type = Integer.class),
      responses = @OpenApiResponse(status = "200", content = @OpenApiContent(from = Account.class))
  )
  public void getOne(Context context) {
    Optional<Account> account = accountRepository.get(contextWrapper.pathParam(context, "id"));

    if (account.isPresent()) {
      contextWrapper.json(context, account.get());
    } else {
      String message = String.format(
          "account with id %s does not exist",
          contextWrapper.pathParam(context, "id")
      );

      Response response = Response.builder()
          .message(message)
          .build();

      contextWrapper.json(context, response, 404);
    }
  }

  @OpenApi(
      method = HttpMethod.GET,
      path = "/account",
      responses = @OpenApiResponse(
          status = "200",
          content = @OpenApiContent(from = Account.class, isArray = true)
      )
  )
  public void getAll(final Context context) {
    contextWrapper.json(context, accountRepository.get());
  }

  @OpenApi(
      method = HttpMethod.POST,
      path = "/account",
      pathParams = {
          @OpenApiParam(name = "name"),
          @OpenApiParam(name = "surname"),
          @OpenApiParam(name = "currency"),
          @OpenApiParam(name = "money")
      },
      responses = @OpenApiResponse(status = "200", content = @OpenApiContent(from = Response.class))
  )
  public void create(final Context context) {
    User user = createUser(context);
    Optional<Account> account = createAccount(context, user);

    if (!account.isPresent()) {
      Response response = Response.builder().message("Invalid money format").build();
      contextWrapper.json(context, response);
      return;
    }

    try {
      accountRepository.create(account.get());
      Response response = Response.builder()
          .message("account created")
          .object(account.get())
          .build();

      contextWrapper.json(context, response);
    } catch (Exception exception) {
      Response response = Response.builder().message(exception.getMessage()).build();
      contextWrapper.json(context, response);
    }
  }

  private User createUser(Context context) {
    return User.builder()
        .id(UUID.randomUUID().toString())
        .name(contextWrapper.formParam(context, "name"))
        .surname(contextWrapper.formParam(context, "surname"))
        .build();
  }

  private Optional<Account> createAccount(Context context, User user) {
    return parseMoney(context)
        .map(money -> Account.builder()
            .number(UUID.randomUUID().toString())
            .user(user)
            .money(money)
            .createdAt(LocalDateTime.now())
            .build()
        );
  }

  private Optional<Money> parseMoney(Context context) {
    try {
      return Optional.of(Money.parse(String.format("%s %s",
          contextWrapper.formParam(context, "currency"),
          contextWrapper.formParam(context, "money"))
      ));
    } catch (Exception exception) {
      return Optional.empty();
    }
  }

  @OpenApi(
      method = HttpMethod.DELETE,
      path = "/account",
      pathParams = @OpenApiParam(name = "id", type = Integer.class),
      responses = @OpenApiResponse(status = "200", content = @OpenApiContent(from = Response.class))
  )
  public void delete(Context context) {
    try {
      accountRepository.delete(contextWrapper.pathParam(context, "id"));

      String message = String.format(
          "account with number %s deleted",
          contextWrapper.pathParam(context, "id")
      );

      Response response = Response.builder()
          .message(message)
          .build();

      contextWrapper.json(context, response);
    } catch (Exception exception) {
      Response response = Response.builder().message(exception.getMessage()).build();
      contextWrapper.json(context, response);
    }
  }

and I registered plugin:

              config.registerPlugin(new OpenApiPlugin(
                      new OpenApiOptions(new Info()
                          .version("1.0")
                          .description("Money Transfer API"))
                          .path("/openapi")
                          .activateAnnotationScanningFor(
                              "com.github.pwittchen.money.transfer.api.controller"
                          )
                  )
              );

Then, when I open ReDoc, I see the following errors in the console:

[main] INFO com.pwittchen.money.transfer.api.Application - server has started
Aug 14, 2019 11:02:53 PM io.javalin.plugin.openapi.dsl.ExtractDocumentationKt getMethodReferenceOfNonStaticJavaHandler
WARNING: Unfortunately it is not possible to match the @OpenApi annotations to the handler in com.pwittchen.money.transfer.api.controller.AccountController. Please add the `path` and the `me
thod` information to the annotation, so the handler can be matched.
Aug 14, 2019 11:02:53 PM io.javalin.plugin.openapi.dsl.ExtractDocumentationKt getMethodReferenceOfNonStaticJavaHandler
WARNING: Unfortunately it is not possible to match the @OpenApi annotations to the handler in com.pwittchen.money.transfer.api.controller.AccountController. Please add the `path` and the `me
thod` information to the annotation, so the handler can be matched.
Aug 14, 2019 11:02:53 PM io.javalin.plugin.openapi.dsl.ExtractDocumentationKt getMethodReferenceOfNonStaticJavaHandler
WARNING: Unfortunately it is not possible to match the @OpenApi annotations to the handler in com.pwittchen.money.transfer.api.controller.AccountController. Please add the `path` and the `me
thod` information to the annotation, so the handler can be matched.
Aug 14, 2019 11:02:53 PM io.javalin.plugin.openapi.dsl.ExtractDocumentationKt getMethodReferenceOfNonStaticJavaHandler
WARNING: Unfortunately it is not possible to match the @OpenApi annotations to the handler in com.pwittchen.money.transfer.api.controller.AccountController. Please add the `path` and the `me
thod` information to the annotation, so the handler can be matched.
Aug 14, 2019 11:02:53 PM io.javalin.plugin.openapi.dsl.ExtractDocumentationKt getMethodReferenceOfNonStaticJavaHandler
WARNING: Unfortunately it is not possible to match the @OpenApi annotations to the handler in com.pwittchen.money.transfer.api.controller.AccountController. Please add the `path` and the `me
thod` information to the annotation, so the handler can be matched.
Aug 14, 2019 11:02:53 PM io.javalin.plugin.openapi.dsl.ExtractDocumentationKt getMethodReferenceOfNonStaticJavaHandler
WARNING: Unfortunately it is not possible to match the @OpenApi annotations to the handler in com.pwittchen.money.transfer.api.controller.AccountController. Please add the `path` and the `me
thod` information to the annotation, so the handler can be matched.
[qtp728885526-17] INFO com.pwittchen.money.transfer.api.Application - 463.79935 ms       GET   /openapi 

It says, I should add path and method to the annotations, but I already did it!

I did everything what documentation says, but I didn’t get expected result. I tried to use this without annotations, but it didn’t work either.

Documentation with ReDoc works in general, but I’m not able to document exact response values and types and other details.

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:12 (9 by maintainers)

github_iconTop GitHub Comments

1reaction
tobias-wallecommented, Aug 17, 2019

@dherges The problem was that you probably used an extended class as a crud handler. As I found out, there were several issues with extended classes.

I created a PR which should fix your problems with the crud handler. https://github.com/tipsy/javalin/pull/712

1reaction
pwittchencommented, Aug 16, 2019

Thanks for finding source of the problem so quickly. I think improving error message will help a lot in diagnosing similar problems in the future.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Problem with OpenAPI plugin (Java+Annotations) #709 - GitHub
I tried to use kotlin-openapi3-dsl plugin with Javalin according to this documentation: https://javalin.io/plugins/openapi In my sample ...
Read more >
Open API v 3.0 Java Annotations Still being called .io.swagger
I am only getting started with openapi/swagger. I understand that Swagger APIs have been Open Sources and that they are now called OpenAPI....
Read more >
There's No Reason to Write OpenAPI By Hand
Some programming languages support a syntax-level feature called "Annotations", for example Java Annotations. An OpenAPI annotation ...
Read more >
Springfox Reference Documentation - GitHub Pages
Springfox 3.x removes dependencies on guava and other 3rd party libraries (not zero dep yet! depends on spring plugin and open api libraries ......
Read more >
Chapter 54. Extending JAX-RS Endpoints with OpenAPI Support
apache.cxf.jaxrs.openapi.OpenApiFeature ) allows you to generate OpenAPI documents by extending published JAX-RS service endpoints with a simple configuration.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found