Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Table of Contents

Introduction

The CXF OpenApiFeature allows you to generate OpenAPI v3.0 documents from JAX-RS service endpoints with a simple configuration. This feature can be configured programmatically in Java or using Spring or Blueprint beans.

Setup

Code Block
xml
xml
<dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-rt-rs-service-description-openapi-v3</artifactId>
    <version>3.2.4</version>
</dependency>

The cxf-rt-rs-service-description-openapi-v3 is only available in 3.2.x and above due to Java 8 baseline. For older releases, as well as for the users of older Swagger specifications 1.x/2.x, there is a dedicated converter provided: org.apache.cxf.jaxrs.swagger.openapi.SwaggerToOpenApiConversionFilter.

Properties

The following optional parameters can be configured in OpenApiFeature. Note that although there are some similarities with Swagger specifications 1.x/2.x, OpenAPI v3.0 is a significant revamp of the specification (in a good sense of it).

NameDescriptionDefault value (if applicable)Sample value (if applicable)
 
configLocation

the OpenAPI configuration location

null/config/openapi-configuration.yml
 
scanKnownConfigLocations

scan known OpenAPI configuration location (classpath or filesystem), which are:

No Format
openapi-configuration.yaml
openapi-configuration.json
openapi.yaml
openapi.json


truetrue
propertiesLocationthe properties file location/swagger.properties /swagger.properties
 
securityDefinitionsa list of security definitions*null

["basicAuth" -> new SecurityScheme().type(Type.HTTP))]

 

customizerthe customizer class instancenullnew OpenApiCustomizer()
 
swaggerUiMavenGroupAndArtifactthe Maven artifacts to pinpoint SwaggerUInull"org.webjars.swagger-ui'
 
swaggerUiVersionthe version of SwaggerUInull"3.13.0"
 
supportSwaggerUiturns on/off SwaggerUI supportnull (== true)true
 
filterClassa security filter**null"com.example.filter.SampleFilter"
 resourceClasses
resourceClassesa list of resource classes which must be scanned**null["com.example.rest.SampleResource"]
 
resourcePackagesa list of package names where resources must be scanned**null["com.example.rest"]
 
ignoredRoutesexcludes specific paths when scanning all resources (see scanAllResources)**null["/api/test"]
 
prettyPrintwhen generating openapi.json, pretty-print the JSON document**truetrue
 
runAsFilterruns the feature as a filterfalsefalse
 
scanScan all JAX-RS resources automaticallytruetrue
 
readAllResourcesRead all operations also with no @Operation** truetrue
 
termsOfServiceUrlthe terms of service URL*nullnull
 
licenseUrlthe license URL*null"http://www.apache.org/licenses/LICENSE-2.0.html"
 
licensethe license*null"Apache 2.0 License"
 
contactUrlthe contact link*nullnull
 
contactEmailthe contact email*null"users@cxf.apache.org"
 
contactNamethe contact name*nullnull
 
descriptionthe description*null"The Sample REST Application with OpenAPI integration"
 
titlethe title*null"Sample REST Application"
 
versionthe version*null"1.0.0"
swaggerUiConfig
 

* - the properties are defined in the OpenAPI class

 ** - the properties are defined in the SwaggerConfiguration class

Configuring from Code

...

import org.apache.cxf.jaxrs.openapi.OpenApiFeature;
import io.swagger.v3.oas.models.security.SecurityScheme;
import io.swagger.v3.oas.models.security.SecurityScheme.Type;

...

final OpenApiFeature feature = new OpenApiFeature();
feature.setContactEmail("cxf@apache.org");
feature.setLicense("Apache 2.0 License");
feature.setLicenseUrl("http://www.apache.org/licenses/LICENSE-2.0.html");           
feature.setSecurityDefinitions(Collections.singletonMap("basicAuth",new SecurityScheme().type(Type.HTTP)));
Swagger UI configurationnullnew SwaggerUiConfig().url("/openapi.json")
useContextBasedConfigIf set, the unique Context Id is going to be generated for each OpenApiContext instance (see please Using Multiple Server Endpoints). Also, you very likely may want to set scan property to false.falsefalse
scannerClassthe name of the JAX-RS API scanner class, used to scope the application, resource packages, resource classes and classpath scanning, please refer to Resource Scanning sectionnullio.swagger.v3.jaxrs2.integration.JaxrsApplicationScanner

* - the properties are defined in the OpenAPI class

 ** - the properties are defined in the SwaggerConfiguration class

Configuring from Code

Code Block
java
java
import org.apache.cxf.jaxrs.openapi.OpenApiFeature;
import io.swagger.v3.oas.models.security.SecurityScheme;
import io.swagger.v3.oas.models.security.SecurityScheme.Type;

...

final OpenApiFeature feature = new OpenApiFeature();
feature.setContactEmail("cxf@apache.org");
feature.setLicense("Apache 2.0 License");
feature.setLicenseUrl("http://www.apache.org/licenses/LICENSE-2.0.html");

 

Configuring from Spring

Code Block
xmlxml
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cxf="http://cxf.apache.org/core"
       xmlns:jaxrs="http://cxf.apache.org/jaxrs"
       xsi:schemaLocation="http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd
           
feature.setSecurityDefinitions(Collections.singletonMap("basicAuth",new SecurityScheme().type(Type.HTTP)));


Configuring from Spring

Code Block
xml
xml
<beans xmlns="http://www.springframework.org/schema/beans"                http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd
                           xmlns:xsi="http://www.springframeworkw3.org/schema/beans 2001/XMLSchema-instance" xmlns:cxf="http://wwwcxf.springframeworkapache.org/schema/beans/spring-beans.xsd">core"
       xmlns:jaxrs="http://cxf... apache.org/jaxrs"
    <!-- JAXRS providers -->
    <bean id="jsonProvider" class="com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider" />
 
    <!-- Application resources -->
    <bean id="sampleResource" class="demo.jaxrs.openapi.server.Sample" />
 
    <!-- CXF OpenApiFeature -->  
    <bean id="openApiFeature" class="org.apache.cxf.jaxrs.openapi.OpenApiFeature xsi:schemaLocation="http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd
                           http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd
                           http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    ... 
    <!-- customize some of the properties JAXRS providers -->
    <bean id="jsonProvider"  </bean>class="com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider" />
 
     ...
<!-- Application resources -->
    <jaxrs:server<bean id="sampleServersampleResource" addressclass="/swaggerSample"demo.jaxrs.openapi.server.Sample" />
 
    <!-- CXF  <jaxrs:serviceBeans>
OpenApiFeature -->  
    <bean      <ref bean="sampleResource" /id="openApiFeature" class="org.apache.cxf.jaxrs.openapi.OpenApiFeature">
        </jaxrs:serviceBeans>
        <jaxrs:providers>
   !-- customize some of the properties -->
    </bean>
 
    ...

     <ref bean<jaxrs:server id="jsonProvidersampleServer" address="/>
        </jaxrs:providers>swaggerSample">
        <jaxrs:features>serviceBeans>
            <ref bean="openApiFeaturesampleResource" />
        </jaxrs:features>
serviceBeans>
        <jaxrs:providers>
            <ref bean="jsonProvider" />
        </jaxrs:server>
</beans>

 

Configuring in Blueprint

providers>
        <jaxrs:features>
            <ref bean="openApiFeature" />
        </jaxrs:features>
    </jaxrs:server>
</beans>


Configuring in Blueprint

In case of Apache Karaf, the OpenAPI v3.0 integration is available as cxf-rs-description-openapi-v3 feature.

...

Code Block
xml
xml
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:cxf="http://cxf.apache.org/blueprint/core"
       xmlns:jaxrs="http://cxf.apache.org/blueprint/jaxrs"
       xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd
                           http://cxf.apache.org/blueprint/core http://cxf.apache.org/schemas/blueprint/core.xsd
                           http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/blueprint/jaxrs.xsd"> 
    ...
    <!-- JAXRS providers -->
    <bean id="jsonProvider" class="com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider" />
 
    <!-- Application resources -->
    <bean id="sampleResource" class="demo.jaxrs.openapi.server.Sample" />
 
 
    <!-- CXF OpenApiFeature -->  
    <bean id="openApiFeature" class="org.apache.cxf.jaxrs.openapi.OpenApiFeature">
        <!-- customize some of the properties -->
    </bean>
 
    ...

    <jaxrs:server id="sampleServer" address="/swaggerSample">
        <jaxrs:serviceBeans>
            <ref component-id="sampleResource" />
        </jaxrs:serviceBeans>
        <jaxrs:providers>
            <ref component-id="jsonProvider" />
        </jaxrs:providers>
        <jaxrs:features>
            <ref component-id="openApiFeature" />
        </jaxrs:features>
    </jaxrs:server>
</blueprint>

 


Configuring in CXFNonSpringJaxrsServlet

Code Block
xml
xml
<web-app>
    <context-param>
        <param-name>contextParam</param-name>
        <param-value>contextParamValue</param-value>
    </context-param>

    <servlet>
        <servlet-name>CXFServlet</servlet-name>
        <display-name>CXF Servlet</display-name>
        <servlet-class>org.apache.cxf.jaxrs.servlet.CXFNonSpringJaxrsServlet</servlet-class>
        <init-param>
            <param-name>jaxrs.serviceClasses</param-name>
            <param-value>org.apache.cxf.systest.jaxrs.BookStore</param-value>
        </init-param>
        <init-param>
            <param-name>jaxrs.features</param-name>
            <param-value>org.apache.cxf.jaxrs.openapi.OpenApiFeature</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
     
    <servlet-mapping>
        <servlet-name>CXFServlet</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
     
</web-app>

Configuring from Property files

It is possible to supply the configuration from the property files. The default location for a properties file is "/swagger.properties". OpenApiFeature will pick it up if it is available, and the location can be overridden with a 'propertiesLocation' property.  Additionally, the complete OpenAPI configuration could be supplied from the property file (usually openapi-configuration.json or openapi-configuration.yml), controlled by 'configLocation' property. Please take into account that there is a certain level of the overlap between both.

Note that the properties, if available, do not override the properties which may have been set as suggested above from the code or Spring/Blueprint contexts or web.xml. Instead they complement and serve as the default configuration properties: for example, if some properties have been set from the code then the values for the same properties found in the properties file will not be used.

Spring Boot Auto Configuration

Please consult samples/jax_rs/spring_boot and on how to create OpenApiFeature as a @Bean and samples/jax_rs/spring_boot_scan on how to auto-enable it.

Enabling Swagger UI

Adding a Swagger UI Maven dependency is all what is needed to start accessing Swagger documents with the help of Swagger UI.

.apache.cxf.jaxrs.openapi.OpenApiFeature</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
     
    <servlet-mapping>
        <servlet-name>CXFServlet</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
     
</web-app>

Configuring from Property files

It is possible to supply the configuration from the property files. The default location for a properties file is "/swagger.properties". OpenApiFeature will pick it up if it is available, and the location can be overridden with a 'propertiesLocation' property.  Additionally, the complete OpenAPI configuration could be supplied from the property file (usually openapi-configuration.json or openapi-configuration.yml), controlled by 'configLocation' property. By default, OpenApiFeature scans for known OpenAPI configuration locations and loads them if available (the behavior could be switched off by setting scanKnownConfigLocations to false). Please take into account that there is a certain level of the overlap between both.

Note that the properties, if available, do not override the properties which may have been set as suggested above from the code or Spring/Blueprint contexts or web.xml. Instead they complement and serve as the default configuration properties: for example, if some properties have been set from the code then the values for the same properties found in the properties file will not be used.

Spring Boot Auto Configuration

Please consult samples/jax_rs/spring_boot and on how to create OpenApiFeature as a @Bean or/and samples/jax_rs/spring_boot_scan on how to auto-enable it. By default, the OpenApiCustomizer instance will be preconfigured for  OpenApiFeature since the base path is often unknown to CXF.

Enabling Swagger UI

Adding a Swagger UI Maven dependency is all what is needed to start accessing Swagger documents with the help of Swagger UI.


Code Block
languagexml
<dependency>
    <groupId>org.webjars</groupId>
    <artifactId>swagger-ui</artifactId>
    <version>3.13.0</version>
</dependency>


For example, let's assume a JAX-RS endpoint is published at 'http://host:port/context/services/'.

Open the browser and go to 'http://host:port/context/services/api-docs/?url=/openapi.json' which will return a Swagger UI page.

CXF Services page will also link to Swagger UI. Go to 'http://host:port/context/services/' and follow a Swagger link which will return a Swagger UI page.

See samples/jax_rs/description_openapi_v3 as an example.

To deactivate automatic Swagger UI integration please set 'supportSwaggerUi' property to "false".

Enabling Swagger UI in OSGi container (Karaf)

Since org.webjars/swagger-ui is just a package with resources, it won't be referenced in OSGi manifest as the required imports. Therefore, to make use of Swagger UI in the OSGi deployments, the org.webjars/swagger-ui should be installed manually, for example:

Code Block
karaf@root()> install mvn:org.webjars/swagger-ui/3.23.8

The dedicated Activator will take care of discovering the presence of the org.webjars/swagger-ui bundle and configuring OpenApiFeature.

Configuring Swagger UI (3.2.7+)

The OpenApiFeature  has a way to pre-configure certain  Swagger UI parameters (https://github.com/swagger-api/swagger-ui/blob/master/docs/usage/configuration.md) through SwaggerUiConfig. Theway it is implemented is by passing those parameters as a query string so the Swagger UI could adjust itself.


Warning

Apache CXF prior to 3.4.6 / 3.5.1 passed Swagger UI configuration (url, ...) as query parameters. Starting from Swagger UI 4.1.3, most of query parameters are not accepted anymore (due to security concerns), and Apache CXF employes different strategy and tries to replace the URL dynamically (inside HTML) when serving Swagger UI's front web page. This behaviour could be turned off by setting queryConfigEnabled  property of the SwaggerUiConfig to true (the default value is false and URLs are replaced dynamically). Please notice that in this case the customized Swagger UI bundle is required since queryConfigEnabled  property could only be set by altering the distribution (https://github.com/swagger-api/swagger-ui/blob/master/docs/usage/configuration.md).

The typical initialization for server-side dynamical URL replacement  looks like this:

Code Block
new SwaggerUiConfig()
    .url("/swagger.json")
    ...
    .queryConfigEnabled(false)

In other words:

  • when queryConfigEnabled  is set to false, Apache CXF will dynamically replace the URL in SwaggerUI, in this respect the value won't be taken from the query string but from url property of the SwaggerUI configuration, this is a default behavior
  • when queryConfigEnabled is set to true, Apache CXF will do nothing and just forward query parameters to SwaggerUI (hoping it will somehow take care of it), in generalthat implies custom SwaggerUI distribution has to be used


Anchor
OpenApiFeature-UsingMultipleServerEndpoints(3.3.0+)
OpenApiFeature-UsingMultipleServerEndpoints(3.3.0+)
Using Multiple Server Endpoints (3.3.0+)

Quite often there are more than one JAXRSServerFactoryBean configured within same Apache CXF application, for example, under "/admin" and "/public" endpoints. The older Swagger/OpenAPI v2.0 integrations used such basePath to disambiguate multiple API documentation contexts, but since OpenAPI v3.0 Specification does not explicitly include the concept of basePath anymore, this approach is not working. Luckily, starting from 2.0.6 release, Swagger OpenAPI v3 implementation properly supports Context Id. To activate it from OpenApiFeature, it is enough to set useContextBasedConfig property to true (very likely you would also want to set scan to false).


Code Block
final OpenApiFeature feature = new OpenApiFeature();
feature.setScan(false);
feature.setUseContextBasedConfig(true);
...

With that, each OpenApiFeature will generate unique Context Id and won't see any classes / packages beyond its own configuration

 

Code Blockxmlxml
<dependency>
    <groupId>org.webjars</groupId>
    <artifactId>swagger-ui</artifactId>
    <version>3.13.0</version>
</dependency>

 

For example, let's assume a JAX-RS endpoint is published at 'http://host:port/context/services/'.

Open the browser and go to 'http://host:port/context/services/api-docs/?url=/openapi.json' which will return a Swagger UI page.

CXF Services page will also link to Swagger UI. Go to 'http://host:port/context/services/services' and follow a Swagger link which will return a Swagger UI page.

See samples/jax_rs/description_openapi_v3 as an example.

To deactivate automatic Swagger UI integration please set 'supportSwaggerUi' property to "false".

Samples

CXF's distribution contains the following samples.