Skip to main content
Redhat Developers  Logo
  • Products

    Featured

    • Red Hat Enterprise Linux
      Red Hat Enterprise Linux Icon
    • Red Hat OpenShift AI
      Red Hat OpenShift AI
    • Red Hat Enterprise Linux AI
      Linux icon inside of a brain
    • Image mode for Red Hat Enterprise Linux
      RHEL image mode
    • Red Hat OpenShift
      Openshift icon
    • Red Hat Ansible Automation Platform
      Ansible icon
    • Red Hat Developer Hub
      Developer Hub
    • View All Red Hat Products
    • Linux

      • Red Hat Enterprise Linux
      • Image mode for Red Hat Enterprise Linux
      • Red Hat Universal Base Images (UBI)
    • Java runtimes & frameworks

      • JBoss Enterprise Application Platform
      • Red Hat build of OpenJDK
    • Kubernetes

      • Red Hat OpenShift
      • Microsoft Azure Red Hat OpenShift
      • Red Hat OpenShift Virtualization
      • Red Hat OpenShift Lightspeed
    • Integration & App Connectivity

      • Red Hat Build of Apache Camel
      • Red Hat Service Interconnect
      • Red Hat Connectivity Link
    • AI/ML

      • Red Hat OpenShift AI
      • Red Hat Enterprise Linux AI
    • Automation

      • Red Hat Ansible Automation Platform
      • Red Hat Ansible Lightspeed
    • Developer tools

      • Red Hat Trusted Software Supply Chain
      • Podman Desktop
      • Red Hat OpenShift Dev Spaces
    • Developer Sandbox

      Developer Sandbox
      Try Red Hat products and technologies without setup or configuration fees for 30 days with this shared Openshift and Kubernetes cluster.
    • Try at no cost
  • Technologies

    Featured

    • AI/ML
      AI/ML Icon
    • Linux
      Linux Icon
    • Kubernetes
      Cloud icon
    • Automation
      Automation Icon showing arrows moving in a circle around a gear
    • View All Technologies
    • Programming Languages & Frameworks

      • Java
      • Python
      • JavaScript
    • System Design & Architecture

      • Red Hat architecture and design patterns
      • Microservices
      • Event-Driven Architecture
      • Databases
    • Developer Productivity

      • Developer productivity
      • Developer Tools
      • GitOps
    • Secure Development & Architectures

      • Security
      • Secure coding
    • Platform Engineering

      • DevOps
      • DevSecOps
      • Ansible automation for applications and services
    • Automated Data Processing

      • AI/ML
      • Data Science
      • Apache Kafka on Kubernetes
      • View All Technologies
    • Start exploring in the Developer Sandbox for free

      sandbox graphic
      Try Red Hat's products and technologies without setup or configuration.
    • Try at no cost
  • Learn

    Featured

    • Kubernetes & Cloud Native
      Openshift icon
    • Linux
      Rhel icon
    • Automation
      Ansible cloud icon
    • Java
      Java icon
    • AI/ML
      AI/ML Icon
    • View All Learning Resources

    E-Books

    • GitOps Cookbook
    • Podman in Action
    • Kubernetes Operators
    • The Path to GitOps
    • View All E-books

    Cheat Sheets

    • Linux Commands
    • Bash Commands
    • Git
    • systemd Commands
    • View All Cheat Sheets

    Documentation

    • API Catalog
    • Product Documentation
    • Legacy Documentation
    • Red Hat Learning

      Learning image
      Boost your technical skills to expert-level with the help of interactive lessons offered by various Red Hat Learning programs.
    • Explore Red Hat Learning
  • Developer Sandbox

    Developer Sandbox

    • Access Red Hat’s products and technologies without setup or configuration, and start developing quicker than ever before with our new, no-cost sandbox environments.
    • Explore Developer Sandbox

    Featured Developer Sandbox activities

    • Get started with your Developer Sandbox
    • OpenShift virtualization and application modernization using the Developer Sandbox
    • Explore all Developer Sandbox activities

    Ready to start developing apps?

    • Try at no cost
  • Blog
  • Events
  • Videos

Normalize web services with Camel K and AtlasMap, Part 2

November 26, 2021
Bruno Meseguer
Related topics:
APIsContainersEvent-DrivenJavaKubernetes
Related products:
Red Hat OpenShift

Share:

    Part 1 of this series introduced a simple approach to normalizing and connecting web services using Camel K, a lightweight cloud-integration platform based on Apache Camel that runs natively on Kubernetes. In this article, we'll walk through the Camel K implementation step-by-step. We'll also cover how to simplify data mapping with AtlasMap.

    Note: Many organizations today face the challenge of using many different services, often as a result of partnerships or acquisitions. These systems are implemented with a range of technologies, each with its own access protocol. The previous article discussed how Apache Camel makes it easy to normalize the APIs in this scenario.

    Camel K implementation

    In Part 1, I presented the following list of key tasks needed to construct our Camel K implementation:

    1. Inspect the service interface for the backend core capability.
    2. Design an OpenAPI definition that simplifies and normalizes access.
    3. Create data mapping definitions for runtime execution.
    4. Define a Camel route that implements the end-to-end flow.

    The order and locations of tasks to be completed.
    Figure 1. The order and locations of tasks to be completed.

    Let's discuss these tasks one at a time.

    Task 1: Inspect the service interface

    Our backend is implemented as an XML-over-REST service, returning subscriber details for a given identifier. Figure 2 illustrates a sample request/response interaction.

    The request to the backend service and its response are both in XML.
    Figure 2. The request to the backend service and its response are both in XML.

    The example repository for this article includes a mock XML-based backend. This will allow us, later in the article, to execute an end-to-end interaction. The stub/end1/ directory in the GitHub repository provided with this article contains a simple endpoint that implements the backend, based on Camel K, along with instructions for running it.

    Task 2: Design the OpenAPI definition

    The front-facing API we need to define is based on the backend API, and also defines a subscriber service. The calling client obtains the details of a subscriber by providing its identifier, as Figure 3 illustrates.

    A client interacts with the OpenAPI interface using JSON requests and responses.
    Figure 3. A client interacts with the OpenAPI interface using JSON requests and responses.

    Note: The base OpenAPI endpoint in this article was created using Apicurio, a graphical tool for designing APIs. We won't dive into the endpoint's definition, but you can explore its contents in the repository's camelk/api/openapi.json file.

    Our new OpenAPI definition and the XML backend are very similar. In essence, they both hold information about the subscriber's full name and its associated postal address. The OpenAPI definition, however, has been simplified to present fewer fields and a flat structure.

    Camel K parses the OpenAPI request and automatically configures REST behaviors, helping to speed up API implementation and make the developer's life that much easier. When running the service, you just need to indicate where to find the OpenAPI definition, using the following command-line option:

    --open-api api/openapi.json

    Camel K takes care of all the API preparations and leaves the developer to focus on the business logic implementation.

    Task 3: Data transformation and mapping with AtlasMap

    Often, services are almost identical except for their data transformations and the APIs they expose, which is somewhat the scene we're replicating. Data mapping is the central task, as shown in Figure 4.

    Transforming data between JSON and XML is the central task for this application.
    Figure 4. Transforming data between JSON and XML is the central task for this application.

    Apache Camel offers a ton of functionality to transform data. Different coding strategies are appropriate, depending on the scenario. Coding options range from out-of-the-box, opinionated transformers to fully customizable ones where complete freedom is given to the developer when custom handling is necessary.

    We won't dive into all the available options but will instead focus on a strategy that aligns with Camel K's. We want to allow the developer to worry less about the underlying mechanics and focus more on the problem at hand.

    There are two distinctive tasks to undertake:

    1. Converting JSON to XML, and vice versa.
    2. Structural field mapping, because the shapes of the JSON and XML data differ.

    Often these steps are implemented in separate stages. In our example, we encapsulate them as one action by defining AtlasMap transformations (Figure 5).

    Our transformation performs two operations in one: XML to JSON with field and structural changes.
    Figure 5. Our transformation performs two operations in one: XML to JSON with field and structural changes.

    AtlasMap is a mapping tool that provides a graphical user interface (GUI) to define the data mappings. It can run embedded or standalone and has a convenient Visual Studio Code (VS Code) extension. The instructions that follow are based on this extension. With the extension installed, you can start and stop AtlasMap from the VS Code command palette (Figure 6).

    ​​The VS Code command palette shows how start (open) and stop AtlasMap.
    Figure 6. ​​The VS Code command palette shows how to start (open) and stop AtlasMap.

    After you start AtlasMap, select the input and output data shapes to use in the graphical tool by clicking the Import instance or schema file button shown in Figure 7.

    The Import instance or schema file button in is at the top right of the AtlasMap screen.
    Figure 7. The Import instance or schema file button is at the top right of the AtlasMap screen.

    Each OpenAPI definition includes samples, but AtlasMap needs to keep them in separate local files. You can find them in the data directory of this article's GitHub repository. Use the following sample files to load the data shapes into AtlasMap:

    • subscriber-request.json (source)
    • subscriber-request.xml (target)

    The front-to-back transformation is trivial. Simply drag and drop, from left to right, the ID field to create the JSON-to-XML mapping as shown in Figure 8.

    Drag the source ID from the left panel to the target ID on the right panel to create the JSON-to-XML mapping.
    Figure 8. Drag the source ID from the left panel to the target ID on the right panel to create the JSON-to-XML mapping.

    Note how AtlasMap indicates that the source is of type JSON and target of type XML.

    The data mapping definition is ready. Export it to your file system as indicated in Figure 9.

    The AtlasMap main menu offers an export action.
    Figure 9. The AtlasMap main menu offers an export action.

    The back-to-front transformation (response flow) merges fields and flattens the data structure. Use the following sample files to load the data shapes into AtlasMap:

    • subscriber-response.xml (source)
    • subscriber-response.json (target)

    To merge the Name and Surname into the JSON fullName field, first drag and drop the Name from left to right, as shown in Figure 10.

    Drag the Name from source to the fullName in the target.
    Figure 10. Drag the Name from source to the fullName in the target.

    Then, do the same for the Surname, as shown in Figure 11.

    Drag the Surname from source to the fullName in the target.
    Figure 11. Drag the Surname from source to the fullName in the target.

    After you map all the fields with similar drag-and-drop actions, the completed definition should look like Figure 12. Export the mapping definition to your local file system.

    Every field in the source is mapped into a field of the target.
    Figure 12. Every field in the source is mapped into a field of the target.

    Task 4: Define the Camel K route

    The OpenAPI specification dedicates the operationId field to identify each REST operation. Camel K expects the developer to define a route that matches the operationId. We use Camel's direct component (for route-to-route invocations) to implement the listener to which Camel K directs incoming traffic.

    The OpenAPI operation and the Camel direct naming need to be in sync as shown in Figure 13. The syntax in the figure uses XML, but Camel K also supports Java, YAML, Groovy, JavaScript, etc.

    The operationId in the OpenAPI definition matches the route in Camel K.
    Figure 13. The operationId in the OpenAPI definition matches the route in Camel K.

    Inside the route, our first action to define is the data transformation. We use Camel's AtlasMap component as follows. A configurable property defines the path to the AtlasMap data model (ADM):

    <!-- REQUEST TRANSFORMATION -->
    <to uri="atlasmap:{{api.resources}}/request.adm"/>
    

    In terms of request-flow processing actions, we're done. We just need to prepare the backend HTTP call by clearing preexisting headers from the incoming call, specifying the HTTP method and content type, and triggering the HTTP invocation:

    <!-- CALL to BACKEND -->
    <removeHeaders pattern="*"/>
    <setHeader name="Exchange.HTTP_METHOD">
      <constant>POST</constant>
    </setHeader>
    <setHeader name="Exchange.CONTENT_TYPE">
      <constant>application/xml</constant>
    </setHeader>
    <to uri="http:{{api.backend1.host}}/camel/subscriber/details"/>

    When Camel executes this code and obtains a response from the backend, it places the reply in the body data holder, and execution resumes in order to process the actions for the response.

    All that is left to include in our flow is our response data transformation to convert the obtained XML response into JSON as per the OpenAPI definition. We use once again the AtlasMap component to define the data mapping:

    <!-- RESPONSE TRANSFORMATION -->
    <to uri="atlasmap:{{api.resources}}/response.adm"/>

    That completes our API exposure service implementation.

    Implementation overview

    The flow diagram in Figure 14 shows the combined results of all the work in the four steps we performed. A client consumes (calls) the OpenAPI service, and Camel K acts as an API translator, which integrates with the existing XML service sitting behind. Because APIs carry out request/response flows, our process needs to implement both directions. Consequently, the integration requires a request conversion (JSON to XML) and a response conversion (XML to JSON).

    The Camel K flow contains three key stages: (1) API exposure, (2) data transformation, and (3) HTTP connectivity to the backend.
    Figure 14. The Camel K flow contains three key stages: API exposure, data transformation, and HTTP connectivity to the backend.

    Run the service

    It is time to put our implementation in motion. Provided you've deployed the Camel K Operator in your Kubernetes platform and have created an integration platform (an instance to run Camel K integrations), the following command deploys and runs our Camel K API:

    kamel run --dev --name api api-route.xml api-spec.xml \
    --open-api api/openapi.json \
    --resource file:api/openapi.json \
    --property file:cfg/svc.properties \
    --resource file:map/request.adm \
    --resource file:map/response.adm

    The options in the command show how the needed resources are specified, including the OpenAPI definition, the data mappings, and the configuration file.

    An additional file in the repository, camelk/api-spec.xml, is an optional resource that helps the API to be discoverable.

    When running the integration in Red Hat OpenShift, Camel K automatically creates a route to access the service externally.

    To discover the API service and obtain its OpenAPI definition, run the following cURL command. The embedded oc command fills in the hostname by obtaining the route name from OpenShift:

    curl http://`oc get route api-layer -o jsonpath='{..spec.host}'`/camel/openapi.json

    To invoke the API as a client, run the following cURL command:

    curl \
    -H "content-type: application/json" \
    -d '{"id":"123"}' \
    http://`oc get route api-layer -o jsonpath='{..spec.host}'`/camel/subscriber/details

    The previous command should produce the following response:

    {
      "fullName": "Some One",
      "addressLine1": "1 Some Street",
      "addressLine2": "Somewhere SOME C0D3",
      "addressLine3": "UK"
    }

    Summary of the Camel K implementation

    The scenario covered in this article is a very real one. Companies have to find a formula that provides them with simplicity, rapid development, and low-cost maintenance.

    Our Camel K implementation is simple and easy to replicate. The developer's basic tasks are:

    1. Transform the request.
    2. Invoke the endpoint.
    3. Transform the response.

    Camel K takes care of everything else. The Camel K Operator builds and natively deploys integrations in Kubernetes, relieving the developer from tedious tasks.

    There is a big trend nowadays to embrace microservices, with many languages and frameworks available for implementing them. This article emphasizes the importance of strategically choosing one framework to provide a standard that ensures a sustainable API development methodology.

    Camel K is the next-generation integration technology for cloud-native environments, bringing supercharged powers of performance, developer joy, no-code binding connectors, serverless capabilities, cloud-native connectivity, and more.

    Next steps with Camel K

    See the following resources to learn more about Camel K and Red Hat's support for it:

    • A good place to start learning about Camel K is the Camel K landing page on Red Hat Developer.
    • See the article Improve cross-team collaboration with Camel K for a fun use case using Camel K.
    • Get a hands-on introduction to Camel K with our collection of interactive tutorials.
    • Learn more about Camel K at the Apache Camel site.
    • Be sure to visit the GitHub repository for the normalized API layer demo featured in this article.
    • Review what you learned by watching the video associated with this article.
    Last updated: October 20, 2023

    Related Posts

    • Six reasons to love Camel K

    • Event-driven serverless applications with Camel K

    • Design event-driven integrations with Kamelets and Camel K

    • Call an existing REST service with Apache Camel K

    Recent Posts

    • AI meets containers: My first step into Podman AI Lab

    • Live migrating VMs with OpenShift Virtualization

    • Storage considerations for OpenShift Virtualization

    • Upgrade from OpenShift Service Mesh 2.6 to 3.0 with Kiali

    • EE Builder with Ansible Automation Platform on OpenShift

    Red Hat Developers logo LinkedIn YouTube Twitter Facebook

    Products

    • Red Hat Enterprise Linux
    • Red Hat OpenShift
    • Red Hat Ansible Automation Platform

    Build

    • Developer Sandbox
    • Developer Tools
    • Interactive Tutorials
    • API Catalog

    Quicklinks

    • Learning Resources
    • E-books
    • Cheat Sheets
    • Blog
    • Events
    • Newsletter

    Communicate

    • About us
    • Contact sales
    • Find a partner
    • Report a website issue
    • Site Status Dashboard
    • Report a security problem

    RED HAT DEVELOPER

    Build here. Go anywhere.

    We serve the builders. The problem solvers who create careers with code.

    Join us if you’re a developer, software engineer, web designer, front-end designer, UX designer, computer scientist, architect, tester, product manager, project manager or team lead.

    Sign me up

    Red Hat legal and privacy links

    • About Red Hat
    • Jobs
    • Events
    • Locations
    • Contact Red Hat
    • Red Hat Blog
    • Inclusion at Red Hat
    • Cool Stuff Store
    • Red Hat Summit
    © 2025 Red Hat

    Red Hat legal and privacy links

    • Privacy statement
    • Terms of use
    • All policies and guidelines
    • Digital accessibility

    Report a website issue