Enterprise Java

Riding Camel on Java EE 7 – REST Services with Swagger Documentation

swagger_java_dsl_camelCamel comes with a bunch of features out of the box. One of them is the Swagger integration. Unfortunately, most of the already-there features heavily rely on Spring. But this should not stop us from using them in plain Java EE 7 applications, because it sometimes is just the more lightweight variant of doing things. But I don’t want to start a discussion about this again. Instead, I think that there is a technology choice for all situations and if you run across a project you just want to use Camel with Java EE 7 and you need REST services and want to document them with Swagger, this is the right post for you.

Bootstrapping Camel in EE 7

The first thing you need, is to bootstrap Camel in a singleton startup bean. I already wrote an article, about how to do this. The other option is to actually use the wildfly-camel subsystem which is also available, but this requires you to be on JBoss WildFly 8.x.

Swagger And Camel Rest Dependencies

The Swagger integration in Camel as of today is supported for Spring applications only. So, to make this work, we do have to implement a bit and configure a bit more than usual. But I promise, that it is not too complicated and done in a minute. Let’s start:

First thing to add to the basic Camel EE 7 example are the additional dependencies for camel:

 <dependency>
            <groupId>org.apache.camel</groupId>
            <artifactId>camel-servlet</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.camel</groupId>
            <artifactId>camel-metrics</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.camel</groupId>
            <artifactId>camel-swagger</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.camel</groupId>
            <artifactId>camel-jackson</artifactId>
        </dependency>

Returning The Camel Context For Swagger

If we can’t use what is there, we need to implement our own CdiRestSwagger-Camel context lookup. There are some things cooking for upcoming Camel versions, but for now we have to do it on our own. Which is surprisingly simple, because we need to overwrite one method of the RestSwaggerApiDeclarationServlet. And this does nothing else than simply return the injected CdiCamelContext.

public class CdiRestSwaggerApiDeclarationServlet extends RestSwaggerApiDeclarationServlet {

    @Inject
    CdiCamelContext context;

    @Override
    public CamelContext lookupCamelContext(ServletConfig config) {
        return context;
    }
}

Some Further Configuration

We’re not done yet. You still have some more configuration to do. As Camel is designed to run in many different environments and there is no specific Java EE 7 version, it still rely on web.xml configuration for the mapping servlets. Please pay extra attention to the CdiRestSwaggerApiDeclarationServlet init-parameters. In this simple example, I did not bother with finding them out, but still rely on them. So, depending on the final name of your application that you set in the Maven build, this needs to be tweaked.

 <context-param>
        <param-name>contextConfigLocation</param-name>
        <!-- to use Java DSL -->
        <param-value>classpath:camel-config.xml</param-value>
 </context-param>

    <!-- to setup Camel Servlet -->
    <servlet>
       <display-name>Camel Http Transport Servlet</display-name>
        <servlet-name>CamelServlet</servlet-name>
        <servlet-class>org.apache.camel.component.servlet.CamelHttpTransportServlet<load-on-startup>1</load-on-startup>
    </servlet>

    <!-- to setup Camel Swagger api servlet -->
    <servlet>
        <!-- we are using our own swagger-cdi binding servlet -->
        <servlet-class>org.apache.camel.component.swagger.CdiRestSwaggerApiDeclarationServlet
        <init-param>
            <param-name>base.path</param-name>
            <param-value>http://localhost:8080/camel/rest</param-value>
        </init-param>
        <init-param>
            <param-name>api.path</param-name>
            <param-value>         http://localhost:8080/camel/api-docs          </param-value>
        </init-param>
        <init-param>
            <param-name>api.version</param-name>
            <param-value>1.2.3</param-value>
        </init-param>
        <init-param>
            <param-name>api.title</param-name>
            <param-value>User Services</param-value>
        </init-param>
        <init-param>
            <param-name>api.description</param-name>
            <param-value>Camel Rest Example with Swagger that provides an User REST service</param-value>
        </init-param>
        <load-on-startup>2</load-on-startup>
    </servlet>

    <!-- swagger api declaration -->
    <servlet-mapping>
        <servlet-name>ApiDeclarationServlet</servlet-name>
        <url-pattern>/api-docs/*</url-pattern>
    </servlet-mapping>

    <!-- define that url path for the Camel Servlet to use -->
    <servlet-mapping>
        <servlet-name>CamelServlet</servlet-name>
        <url-pattern>/rest/*</url-pattern>
    </servlet-mapping>

    <!-- enable CORS filter so people can use swagger ui to browse and test the apis -->
    <filter>
        <filter-name>RestSwaggerCorsFilter</filter-name>
        <filter-class>org.apache.camel.component.swagger.RestSwaggerCorsFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>RestSwaggerCorsFilter</filter-name>
        <url-pattern>/api-docs/*</url-pattern>
        <url-pattern>/rest/*</url-pattern>
    </filter-mapping>

Enough Configuration – To The Logic!

When you’re done with that, you need some logic. The example I’m using here was taken from the official Camel examples and is called camel-example-servlet-rest-tomcat. Please note, that this example contains both, a XML DSL based definition and the Java DSL based definition of the rest-service. I only used the Java DSL and specifically the route defined in the UserRouteBuilder class.

Make sure to add a @Named annotation to the UserService and the User and add the route from the UserRouteBuilder to your startup bean.

   context.addRoutes(new UserRouteBuilder());

That is it. Now you can browser your API by accessing http://localhost:8080/camel/api-docs. If you want to use the Swagger UI you have to add it to your application. The example application contains everything in the build section, that is needed to do this. So, have a look at the complete GitHub project to find out how to browse the API with the Swagger UI.

Markus Eisele

Markus is a Developer Advocate at Red Hat and focuses on JBoss Middleware. He is working with Java EE servers from different vendors since more than 14 years and talks about his favorite topics around Java EE on conferences all over the world. He has been a principle consultant and worked with different customers on all kinds of Java EE related applications and solutions. Beside that he has always been a prolific blogger, writer and tech editor for different Java EE related books. He is an active member of the German DOAG e.V. and it's representative on the iJUG e.V. As a Java Champion and former ACE Director he is well known in the community. Follow him on Twitter @myfear.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Back to top button