Creating a REST API in Apache Camel

Updated:

You’ve learned the basics of Apache Camel. You now know how to process an incoming message. (That’s all you need to do, isn’t it? Job done! K thanks bye! 👋)

Of course, receiving a message is probably not all you’ll need to do.

You’ll probably want to work with web services. Perhaps you want to consume a REST API. Or you need to integrate with some old SOAP system (don’t worry, SOAP lovers, Camel has got your back too).

In this tutorial, you’ll learn how to use Camel to create a REST service.

Related reading - If you’re not familiar with Apache Camel, then I encourage you to read the first part of my Apache Camel Tutorial

How do you create a REST service with Camel?

There are, perhaps confusingly, a gazillion different ways of creating a REST service with Camel.

You can choose to either add Camel to your existing web services app, or you can let Camel do the work, and drive the whole REST thing.

However the most common ways of creating REST services in Camel are:

  • Integrating with JAX-RS: If you’ve already built a REST service with the JAX-RS specification (for example, using a framework like Apache CXF), then you can use Camel to implement the logic behind your web services.
  • Deploying a REST service as a Java servlet: This deploys your REST service using Camel’s servlet component, which means your service runs in a container like Tomcat or Wildfly.
  • Camel’s Restlet component: This is a Camel component for the Restlet framework for Java, which is a REST library in its own right.
  • Using the REST DSL to configure servlets, restlets, and lots more. (Hint: I prefer this option)

The REST DSL

Camel introduced a REST DSL in Camel 2.14. It’s an extension to Camel’s existing DSL, specifically suited to describing REST services. It’s easy to write and configure.

The REST DSL is like syntactic sugar on top of the other components listed above. It makes it easy to create REST services, without having to know too much of the underlying detail.

It sits on top of other components like Jetty or Undertow which actually host your REST service. You don’t need to worry about those details for now, as Camel will set you up with most of the defaults.

The REST DSL is a good place to start when creating new REST services in Camel. So let’s have a look at how you set it up.

Example - Creating a RESTful service in Camel using the REST DSL

In the following steps you’re going to create a RESTful service in Camel, using the REST DSL.

  1. Create a new Camel project.

  2. In the RouteBuilder of your new project, add a restConfiguration() element.

    This initialises the component that will host your REST service. We do this first before defining any endpoints for the service.

    Where you define your CamelContext, add a restConfiguration instruction:

    Java DSL

    public void configure() throws Exception {
        restConfiguration().host("localhost").port("8080");
        // Endpoints will be defined here
    }
    

    XML DSL

    <camelContext xmlns="http://camel.apache.org/schema/spring">
        <restConfiguration host="localhost" port="8080"/>
        <!-- Endpoints will be defined here -->
    </camelContext>
    

    As you can see, this service is going to be hosted on localhost on port 8080.

  3. Define a REST endpoint, and add skeletons for each of your operations - GET, POST, etc.

    First, define a REST endpoint, using rest, with the path (URI) of your service. Then append each of your operations - these are your HTTP verbs.

    The syntax for each operation looks just like a familiar Camel route. However, instead of from, we start each operation with the HTTP verb you want to use, e.g. get, post, delete, etc.

    Like this:

    Java DSL

    rest("/customers")
        .get().to("...").endRest()
        .post().to("...");
    

    XML DSL

    <rest path="/customers">
        <get>
            <to uri="..."/>
        </get>
        <post>
            <to uri="..."/>
        </post>
    </rest>
    

    Notice that in the Java DSL, you need to add an .endRest() to each line, before defining your next HTTP verb.

    A note about REST HTTP verbs - Remember that REST architecture encourages the use of HTTP verbs to describe the action you’re taking on a resource. See the end of this article for a reminder about which verb should be used when.

  4. Now build each of your Camel routes for your REST operations. Here’s an example of a REST service that’s been filled out:

    Java DSL

    rest("/customers")
        .get().to("bean:customerService?method=listCustomers").endRest()
        .post().to("jms:queue:CUSTOMERS");
    

    XML DSL

    <rest path="/customers">
        <get>
            <to uri="bean:customerService?method=listCustomers"/>
        </get>
        <post>
            <to uri="direct:post"/>
        </post>
    </rest>
    

    As you can see, the GET operation passes the request to be serviced by a bean, customerService. But the POST operation passes the request to a Direct component, direct:post.

  5. When you need to read a parameter from the URL – like a Customer ID, or Product ID – then you need to:

    • Define a placeholder in your operation’s URI.
    • Fetch your variable later from a Header of the same name

    For example: if you define a placeholder called {id} in the uri parameter, then you can later retrieve it as a Camel Header called id.

    Here’s an example - a delete REST operation which takes a customer ID. The parameter {id} is declared in the uri - e.g. /customers/12345. It can then be retrieved using ${header.id}:

    Java DSL

    rest("/customers")
        .delete("{id}").to("bean:customer?method=delete(${header.id})");
    

    XML DSL

    <rest path="/customers">
        <delete uri="{id}">
            <to uri="bean:customer?method=delete(${header.id})"/>
        </delete>
    </rest>
    

    In this example, I could implement a method like this in my customer bean, which would get my id value:

    public void delete(String id) {
        // Your code would get the `id` value here
        return "Deleting customer " + id;
    }
    
  6. That’s it! Now keep building up your REST API with as many endpoints and operations as you need.

Comments? Please leave your thoughts below!

Leave a Comment