Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • 00:02
    dependabot[bot] labeled #2685
  • 00:02
    dependabot[bot] labeled #2685
  • 00:02
    dependabot[bot] opened #2685
  • 00:02

    dependabot[bot] on maven

    build(deps): bump groovy-all fr… (compare)

  • 00:02
    dependabot[bot] labeled #2684
  • 00:02
    dependabot[bot] labeled #2684
  • 00:02
    dependabot[bot] opened #2684
  • 00:02

    dependabot[bot] on maven

    build(deps): bump logback-class… (compare)

  • 00:02
    dependabot[bot] labeled #2683
  • 00:02
    dependabot[bot] labeled #2683
  • 00:02
    dependabot[bot] opened #2683
  • 00:02

    dependabot[bot] on maven

    build(deps): bump flyway-core f… (compare)

  • 00:01
    dependabot[bot] labeled #2682
  • 00:01
    dependabot[bot] labeled #2682
  • 00:01
    dependabot[bot] opened #2682
  • 00:01

    dependabot[bot] on maven

    build(deps-dev): bump jmh-gener… (compare)

  • 00:01
    dependabot[bot] labeled #2681
  • 00:01
    dependabot[bot] labeled #2681
  • 00:01
    dependabot[bot] opened #2681
  • 00:01

    dependabot[bot] on maven

    build(deps): bump maven-enforce… (compare)

Will
@williamjtodd
Is there a suggested way to get it loaded?
Nguyen Huu Tuan
@snowyukischnee
Hi,
I'm new to jooby. How can I using jooby-openapi to generate api specs with out having to define all the api in the same class?
Edgar Espina
@jknack
@williamjtodd There is a static call: LogConfigurer.configure(new EnvironmentOptions().getActiveNames());
@snowyukischnee Hi, welcome. Try the mvc/controller model
Nguyen Huu Tuan
@snowyukischnee
@jknack Hi, when i try to define the mvc controller in the same class which is mainClass in jooby-openapi plugin then the generated openapi.yaml was generated fine, but if i move the controller to an another place then the generated spec was not contain the api spec of that controller
i was seperated the route definitions, app config to another place by writing class which consume Jooby instance like AppConfig and RouteConfig, both those class are inherit Extension interface
Edgar Espina
@jknack
Controller are generated OK, just make sure to register the controller from the application
Routes from Extension are not considered
but this should works OK:
class MyApp extends Jooby {
   {
       mvc(new MyController());
   }
}
MyController can be in his own file, no need to have in same file as MyApp
Nguyen Huu Tuan
@snowyukischnee

@jknack Here is my application code

@OpenAPIDefinition(
        info = @Info(
                title = "Title",
                description = "description",
                termsOfService = "Terms",
                contact = @Contact(
                        name = "Jooby",
                        url = "https://jooby.io",
                        email = "support@jooby.io"
                ),
                license = @License(
                        name = "Apache",
                        url = "https://jooby.io/LICENSE"
                ),
                version = "10"
        ),
        tags = @Tag(name = "mytag")
)
public class App extends Jooby{

    public static void main(String[] args) {
        Jooby.runApp(args, app -> {
            // app name
            app.setName(App.class.getSimpleName());
            // configs
            app.install(new AppConfig());
            app.install(new RouterConfig());
        });
    }
}

here is the class that import the mvc controller

public class RouterConfig implements Extension {

    @Override
    public void install(@Nonnull Jooby app) throws Exception {
        app.mvc(CustomerController.class);
    }
}

here is the controller

@Path("/customer")
public class CustomerController {

    @Operation(
            summary = "Find a pet by ID",
            description = "Find a pet by ID or throws a 404"
    )
    @Path("/v")
    @GET
    public Object test() {
        return "!";
    }
}

but the generated api specs return this

openapi: 3.0.1
info:
  title: Title
  description: description
  termsOfService: Terms
  contact:
    name: Jooby
    url: https://jooby.io
    email: support@jooby.io
  license:
    name: Apache
    url: https://jooby.io/LICENSE
  version: "10"
tags:
- name: mytag
paths: {}
Edgar Espina
@jknack
Yea, that is what I tried to explain before
This is not supported:
public class RouterConfig implements Extension {

    @Override
    public void install(@Nonnull Jooby app) throws Exception {
        app.mvc(CustomerController.class);
    }
}
Routes from extension are considered internal or infrastructure, not part of an API
Remove that class and just do:
public class App extends Jooby{

    public static void main(String[] args) {
        Jooby.runApp(args, app -> {
            // app name
            app.setName(App.class.getSimpleName());
            // configs
            app.install(new AppConfig());
            app.mvc(CustomController.class);
        });
    }
}
Nguyen Huu Tuan
@snowyukischnee
so passing Jooby instance to another class to perform the route definition is not supported, right
Edgar Espina
@jknack
correct
openapi scanner traverse known API calls (except for Extensions)
Nguyen Huu Tuan
@snowyukischnee
it will follow the code inside that class, not the jooby instance itself, am i correct
Edgar Espina
@jknack
yes
Nguyen Huu Tuan
@snowyukischnee

i've work around this problem by move the OpenAPIDefinition to the RouterConfig class

@OpenAPIDefinition(
        info = @Info(
                title = "Title",
                description = "description",
                termsOfService = "Terms",
                contact = @Contact(
                        name = "Jooby",
                        url = "https://jooby.io",
                        email = "support@jooby.io"
                ),
                license = @License(
                        name = "Apache",
                        url = "https://jooby.io/LICENSE"
                ),
                version = "10"
        ),
        tags = @Tag(name = "mytag")
)
public class RouterConfig implements Extension {

    @Override
    public void install(@Nonnull Jooby app) throws Exception {
        app.mvc(CustomerController.class);
    }
}

and create my customized openapi module

public class CustomOpenAPIModule extends OpenAPIModule {

    private Class<?> apiDefinitionClass;

    public CustomOpenAPIModule(Class<?> apiDefinitionClass) {
        super();
        this.apiDefinitionClass = apiDefinitionClass;
    }

    @Override
    public void install(@Nonnull Jooby application) throws Exception {
        String dir = Optional.ofNullable(apiDefinitionClass.getPackage()).map(Package::getName).orElse("/").replace(".", "/");
        String appname = apiDefinitionClass.getSimpleName();
        Field fFormat = getClass().getSuperclass().getDeclaredField("format");
        fFormat.setAccessible(true);
        EnumSet<Format> format = (EnumSet<Format>) fFormat.get(this);
        Field fopenAPIPath = getClass().getSuperclass().getDeclaredField("openAPIPath");
        fopenAPIPath.setAccessible(true);
        String openAPIPath = (String) fopenAPIPath.get(this);
        for (Format ext : format) {
            String filename = String.format("/%s.%s", appname, ext.name().toLowerCase());
            String openAPIFileLocation = Router.normalizePath(dir) + filename;
            application.assets(Router.noTrailingSlash(Router.normalizePath(openAPIPath + "/openapi." + ext.name().toLowerCase())), openAPIFileLocation);
        }
        Method mConfigureUI = getClass().getSuperclass().getDeclaredMethod("configureUI", Jooby.class);
        mConfigureUI.setAccessible(true);
        mConfigureUI.invoke(this, application);
    }
}

and this is work fine except my code will be bad

Edgar Espina
@jknack
Ok, but why?
why do you need to put the controller inside an Extension?
for example, you are forking how it works and might miss something new from module (like bug fixing, new features, etc)
Also, open-api doesn’t use reflection and your version does it… not necessarily bad but not need it
Nguyen Huu Tuan
@snowyukischnee
yes, this is just a workaround
since my project structure that will seperate the route register from the main app
the App class contains no information about it will has route A or route B
I just move the definition to another to do that
Edgar Espina
@jknack
don’t get it
but if you ruly want this, try this instead: https://jooby.io/#router-composing-routes
So you still have your “MainApp"
Nguyen Huu Tuan
@snowyukischnee
yes
Edgar Espina
@jknack
then you create N more routers and from there you register the mvc controllers
Nguyen Huu Tuan
@snowyukischnee
i just dont want to define everything inside my main
Edgar Espina
@jknack
class A extens Jooby {
   {
      mvc(Controller.class);
   }
}
Then:
Nguyen Huu Tuan
@snowyukischnee
public static void main(String[] args) {
        Jooby.runApp(args, app -> {
            // app name
            app.setName(App.class.getSimpleName());
            app.install(new GracefulShutdown());
            app.decorator(new AccessLogHandler());
            app.error(new HttpDefaultJsonHandler());
            // metrics
            app.install(new MetricsModule("/actuator")
                    .threadDump()
                    .ping()
                    .healthCheck("deadlock", new ThreadDeadlockHealthCheck())
                    .metric("memory", new MemoryUsageGaugeSet())
                    .metric("threads", new ThreadStatesGaugeSet())
                    .metric("gc", new GarbageCollectorMetricSet())
                    .metric("fs", new FileDescriptorRatioGauge())
            );
            // openapi
            app.install(new CustomOpenAPIModule(RouterConfig.class));
            // dependency injection
            app.install(new GuiceModule(
                    // inject here
            ));

            app.mvc(CustomerController.class);
        });
    }
like this
Edgar Espina
@jknack
Jooby.runApp(args, app -> {
    app.use(new A());
})
that is supported by open api
and follow the design/goal of extensions: infrasture support
Nguyen Huu Tuan
@snowyukischnee
so I'll have to define every config inside the instance?
since I've familiar with spring and I just want to rewrite my project using a different framework
Edgar Espina
@jknack
don’t follow
What you show me, looks good. Just remove the install you did for your custom module:
```
public static void main(String[] args) {
        Jooby.runApp(args, app -> {
            // app name
            app.setName(App.class.getSimpleName());
            app.install(new GracefulShutdown());
            app.decorator(new AccessLogHandler());
            app.error(new HttpDefaultJsonHandler());
            // metrics
            app.install(new MetricsModule("/actuator")
                    .threadDump()
                    .ping()
                    .healthCheck("deadlock", new ThreadDeadlockHealthCheck())
                    .metric("memory", new MemoryUsageGaugeSet())
                    .metric("threads", new ThreadStatesGaugeSet())
                    .metric("gc", new GarbageCollectorMetricSet())
                    .metric("fs", new FileDescriptorRatioGauge())
            );
            // openapi
            app.install(new OpenApiModule());
            // dependency injection
            app.install(new GuiceModule(
                    // inject here
            ));

            app.mvc(CustomerController.class);
        });
    }
```