Javier Aviles
Javier Aviles

Reputation: 10665

BeanConfig (or similar?) in Swagger 2.0 (OpenApi 3.0)

I am currently migrating our API docs (which were Swagger 1.5) to Swagger 2.0 (OpenApi 3.0)

The API docs are Swagger docs which get generated with java annotations using maven packages swagger-annotations and swagger-jaxrs. I have already updated the pom.xml with new versions so it looks like:

        <dependency>
            <groupId>io.swagger.core.v3</groupId>
            <artifactId>swagger-annotations</artifactId>
            <version>2.0.6</version>
        </dependency>
        <dependency>
            <groupId>io.swagger.core.v3</groupId>
            <artifactId>swagger-jaxrs2</artifactId>
            <version>2.0.6</version>
        </dependency>

And also all the old annotations are replaced with the new ones (which change quite a lot) and looks fine.

The thing is we were using a BeanConfig to define the docs general config and auto-scan all the REST resources so the documentation got generated automatically at /swagger.json.

The problem is I can't find the "new way" of doing such thing as creating a BeanConfig and auto-scan the resources so everything gets generated at /swagger.json or /openapi.json (maybe now is something like OpenAPIDefinition?)

If somebody could point me to the right direction I would be very grateful...

Upvotes: 12

Views: 11174

Answers (4)

Matthew
Matthew

Reputation: 11337

Another variant on the same theme. You can package up your openAPI config generation logic into a stand-alone class like so:

    @Provider
    public class SwaggerInfoBlackMagic implements Feature {
        @Context ServletConfig config;
        @Context Application app;

        @Override
        public boolean configure(FeatureContext context) {
            //The aim here is to force construction of a (convincing) OpenApiContext before swagger does!
            //This has been lifted from BaseOpenApiResource
            String ctxId = getContextIdFromServletConfig(config);
            try {
                OpenApiContext ctx = new JaxrsOpenApiContextBuilder()
                        .servletConfig(config)
                        .application(app)
                        //Might need more of these depending on your setup..
                        //.resourcePackages(resourcePackages)
                        //.configLocation(configLocation)
                        .openApiConfiguration(getOpenApi())
                        .ctxId(ctxId)
                        .buildContext(true); //this also stores the instance statically
            } catch (OpenApiConfigurationException e) {
                throw new RuntimeException(e);
            }
            return true;
        }


        private OpenAPIConfiguration getOpenApi() {...}
    }

Then whenever you need it you can simply add:

jersey().register(SwaggerInfoBlackMagic.class);

It's the same as the above but slightly tidier.

Upvotes: 0

Atul Kr Dey
Atul Kr Dey

Reputation: 160

There is a much simpler solution for the above requirement.

import io.swagger.v3.jaxrs2.integration.resources.OpenApiResource;
import io.swagger.v3.oas.annotations.OpenAPIDefinition;
import io.swagger.v3.oas.annotations.info.Contact;
import io.swagger.v3.oas.annotations.info.Info;
import org.glassfish.jersey.server.ResourceConfig;


@OpenAPIDefinition(
    info =
        @Info(
            title = "Sample rest service",
            version = "1.0.0",
            description = "Sample rest service",
            contact =
                @Contact(
                    url = "https://jira2.cerner.com/projects/Dey",
                    name = "ADey")))
public class SampleRestApplication extends ResourceConfig {
  public SampleRestApplication() {
    register(OpenApiResource.class);
  }
}

your service will load your API spec at /openApi.yaml|json.

Upvotes: 2

Javier Aviles
Javier Aviles

Reputation: 10665

After some research, I could find some documentation about it in their Github for JAX-RS application, so the result is something similar to what I was doing but now instead of using a BeanConfig, it uses OpenAPI and Info:

@ApplicationPath("/sample")
public class MyApplication extends Application {

    public MyApplication(@Context ServletConfig servletConfig) {
        super();
        OpenAPI oas = new OpenAPI();
        Info info = new Info()
            .title("Swagger Sample App bootstrap code")
            .description("This is a sample server Petstore server.  You can find out more about Swagger " +
                    "at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/).  For this sample, " +
                    "you can use the api key `special-key` to test the authorization filters.")
            .termsOfService("http://swagger.io/terms/")
            .contact(new Contact()
                    .email("[email protected]"))
            .license(new License()
                    .name("Apache 2.0")
                    .url("http://www.apache.org/licenses/LICENSE-2.0.html"));

        oas.info(info);
        SwaggerConfiguration oasConfig = new SwaggerConfiguration()
            .openAPI(oas)
            .prettyPrint(true)
            .resourcePackages(Stream.of("io.swagger.sample.resource").collect(Collectors.toSet()));

        try {
            new JaxrsOpenApiContextBuilder()
                .servletConfig(servletConfig)
                .application(this)
                .openApiConfiguration(oasConfig)
                .buildContext(true);
        } catch (OpenApiConfigurationException e) {
            throw new RuntimeException(e.getMessage(), e);
        }

    }
}

Upvotes: 10

tryingToLearn
tryingToLearn

Reputation: 11659

Though OP has answered their own question, but adding a few more details for people like me who landed on this post as I wanted to migrate from swagger 1.x to swagger 2.0 (openAPI 3) and needed complete config.

(This example is for embedded jetty)

// Jetty configuration

// ContextHandlerCollection contexts

ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/api");
context.addFilter(GzipFilter.class, "/*", EnumSet.allOf(DispatcherType.class));

ResourceConfig resourceConfig = new ResourceConfig(ImmutableSet.<Class<?>>builder()
                                                                .add(MyRestService.class)
                                                                .build());
resourceConfig.registerClasses(OpenApiResource.class,AcceptHeaderOpenApiResource.class); // for swagger, this will cerate openapi.json at <host>/api/openapi.json
context.addServlet(new ServletHolder(new ServletContainer(resourceConfig)), "/*");
contexts.addHandler(context);   

If you need to change default swagger config, that can be done by what OP has described in their answer:

OpenAPI oas = new OpenAPI();
        Info info = new Info()
            .title("Swagger Sample App bootstrap code")
            .description("This is a sample server Petstore server.  You can find out more about Swagger " +
                    "at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/).  For this sample, " +
                    "you can use the api key `special-key` to test the authorization filters.")
            .termsOfService("http://swagger.io/terms/")
            .contact(new Contact()
                    .email("[email protected]"))
            .license(new License()
                    .name("Apache 2.0")
                    .url("http://www.apache.org/licenses/LICENSE-2.0.html"));

        oas.info(info);
        SwaggerConfiguration oasConfig = new SwaggerConfiguration()
            .openAPI(oas)
            .prettyPrint(true)
            .resourcePackages(Stream.of("io.swagger.sample.resource").collect(Collectors.toSet()));

        try {
            new JaxrsOpenApiContextBuilder()
                .servletConfig(servletConfig)
                .application(this)
                .openApiConfiguration(oasConfig)
                .buildContext(true);
        } catch (OpenApiConfigurationException e) {
            throw new RuntimeException(e.getMessage(), e);
        }

Upvotes: 5

Related Questions