How do you invoke a REST API using Apache Camel’s HTTP component?

Calling a RESTful service from Apache Camel

We often need to integrate with other services.

For example, we might want to integrate with the Stripe API to process payments. Or we might have a company internal REST API that we need to talk to. Most modern APIs now use the REST style, which is great as it’s fairly lightweight and easy to use.

So how do you invoke a REST service from Camel? Which component should you use?

In this article I’ll share what I think is the easiest way to call an external web service from Camel, and share some example code that you can use.

What do we need from our Camel kit bag?

Figuring out how to implement something in Apache Camel can be a bit overwhelming when you’re a beginner. Where do you even start?

We want to invoke a REST API. So let’s take a look at what we need to do, step-by-step:

  • First, we need something to trigger the REST request. In Camel, we’re always responding to a trigger or event. A Camel route always starts with some component, which acts as the trigger.

    So… I’ll use a Timer component to start the route, which will fire the route immediately. But you could start your route with something else, like a Direct component or a JMS component.

  • We need to build up a URL dynamically. We might need to modify some parts of the REST API URL, depending on values that we know about. For example, the URL of the REST API might change, depending on the username of the requester, or the Product ID that you’re trying to retrieve.

    So… I’ll use the ToD EIP in Camel, which is one way to send a message to an endpoint, if the URL needs to be dynamic. It’s useful if the URL can only be known at runtime. You can also use the Recipient List pattern for this.

  • We need to make an HTTP request. Calling a REST service is basically just making a simple HTTP request, and there are lots of different ways to do this in Camel. We just need to use a component which can be used as an HTTP client.

    So… I’ll use Camel’s HTTP component (previously called the “HTTP4” component). It’s a simple HTTP client, that we can use to make GET requests, POST requests, or anything we want.

Invoking a REST service from Camel - step-by-step

Let’s do it! Let’s invoke a REST service using Apache Camel.

To be able to follow the steps in this tutorial, you already need to have Apache Camel set up in your project.

Don’t have a Camel project yet? If you don’t have Camel added into your project, go to the Spring Initializr to create a new Spring Boot app with Camel support, or create a new Camel project from a Maven archetype.

This code has been verified with Apache Camel 3.0.0.

  1. Let’s add our Maven dependencies. In the section above, I said we’re going to use the HTTP component. It’s a simple HTTP client, which is perfect for us.

    To use it, you need to add the camel-http dependency to your Maven POM:

    <dependency>
      <groupId>org.apache.camel</groupId>
      <artifactId>camel-http</artifactId>
    </dependency>
    

    Using a version of Camel prior to 3.0? You’ll need to use the dependency camel-http4. The component was renamed in Camel 3 and the number 4 was dropped.

  2. Let’s add a new Camel route to our RouteBuilder class. This route will call the external web service.

    I’m going to start the route with a Timer, just to make it easy to run.

    from("timer:mytimer?repeatCount=1")
      //....the rest of the route will go here.
    

    Notice how I’m setting the repeat counter to 1, so that it only executes once.

    Depending on your app, you might want to start this route with a Direct component instead, or perhaps a JMS component if you’re reading from a queue.

  3. Set the body of the request. We do this using the setBody step. The contents of the Body will be used when making the HTTP request.

    I’m going to send some arbitrary JSON, just some information about a cat: 🐈

    .setBody(simple("{ \"cat\": \"Milo\" }"))
    

    If you’re making a GET request to your REST API, you shouldn’t need this step. So you can set the body to null if you prefer:

    .setBody(simple("${null}"))
    
  4. Using Camel’s toD pattern to create a dynamic URI, we build the target URL that we want to invoke. The URL begins with http, which will use the HTTP component we added above:

    .toD("http://www.examplecat.com/cats/${header.catName}" +
        "?httpMethod=POST")
    

    We add httpMethod, to tell the HTTP component to set which HTTP action (verb) we want to use. If you need to use GET, PUT, or something else, you just need to update this property.

  5. Now do something with the response from the RESTful service. Once we’ve made the request, we can access the response in the Camel Exchange Body, e.g.:

    .log("The body was - ${body}");
    

Adding authentication (optional)

Need to provide a username and password to the REST request? You can use the auth parameters, like this:

.toD("http://www.examplecat.com/cats/${header.catName}" +
    "?httpMethod=GET" +
    "&authMethod=Basic" +
    "&authUsername=" +
    "&authPassword=" +
    "&authenticationPreemptive=true")

This will pass credentials using Basic HTTP authentication.

A complete example and sample code

Let’s put it all together.

The following example Camel route calls a RESTful service. It uses the GitHub API to ‘star’ the Apache Camel repository using your account.

from("direct:addstar")

    // Set up some variables for our HTTP request - we'll use these later!
    .setHeader("repoOwner", constant("apache"))
    .setHeader("repoName", constant("camel"))

    // Set the body to null, because it is required by the GitHub API.
    .setBody(simple("${null}"))

    // Now invoke the GitHub API with the null Body
    // PUT /user/starred/:owner/:repo
    .toD("https://api.github.com/user/starred/${header.repoOwner}/${header.repoName}" +
            "?httpMethod=PUT" +
            "&authMethod=Basic" +
            "&authUsername=XXX" +
            "&authPassword=XXX" +
            "&authenticationPreemptive=true")

    .log("Response code from the operation was: ${header.CamelHttpResponseCode}");

If you want to run this demo, set up a Personal Access Token in your GitHub account and then grab the source code in the Git repo below:

See the example code on GitHub

Leave a Comment

You can use Markdown in your comment. To write code, indent lines by 4 spaces.