惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

D
Darknet – Hacking Tools, Hacker News & Cyber Security
V
Vulnerabilities – Threatpost
Cloudbric
Cloudbric
G
GRAHAM CLULEY
S
Securelist
Schneier on Security
Schneier on Security
Help Net Security
Help Net Security
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Project Zero
Project Zero
Spread Privacy
Spread Privacy
P
Privacy International News Feed
C
Cyber Attacks, Cyber Crime and Cyber Security
Cisco Talos Blog
Cisco Talos Blog
T
Tailwind CSS Blog
博客园_首页
有赞技术团队
有赞技术团队
Simon Willison's Weblog
Simon Willison's Weblog
Stack Overflow Blog
Stack Overflow Blog
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Latest news
Latest news
T
Tor Project blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Attack and Defense Labs
Attack and Defense Labs
www.infosecurity-magazine.com
www.infosecurity-magazine.com
O
OpenAI News
J
Java Code Geeks
T
Tenable Blog
K
Kaspersky official blog
AWS News Blog
AWS News Blog
S
Security @ Cisco Blogs
The GitHub Blog
The GitHub Blog
T
Threatpost
月光博客
月光博客
H
Heimdal Security Blog
Security Latest
Security Latest
The Hacker News
The Hacker News
Y
Y Combinator Blog
A
Arctic Wolf
Apple Machine Learning Research
Apple Machine Learning Research
C
Cisco Blogs
美团技术团队
Microsoft Security Blog
Microsoft Security Blog
Hugging Face - Blog
Hugging Face - Blog
T
The Blog of Author Tim Ferriss
C
CERT Recently Published Vulnerability Notes
D
Docker
Google Online Security Blog
Google Online Security Blog
D
DataBreaches.Net
V
Visual Studio Blog
H
Help Net Security

Piotr's TechBlog

Deep Dive into Kafka Offset Commit with Spring Boot Claude Code Template for Spring Boot Speed up Java Startup with Spring Boot and Project Leyden Local AI Models with LM Studio and Spring AI AI Models in Containers with RamaLama Claude Code on OpenShift with vLLM and Dev Spaces Create Apps with Claude Code on Ollama Spring AI with External MCP Servers Istio Spring Boot Library Released Startup CPU Boost in Kubernetes with In-Place Pod Resize
Quarkus REST with Apache Camel and Keycloak - Piotr's TechBlog
piotr.minkowski · 2026-06-23 · via Piotr's TechBlog

In this article, you’ll learn how to build a REST API using Apache Camel on top of Quarkus. We’ll cover the Camel REST DSL with the platform-http component, data persistence with Hibernate Panache, authentication with Quarkus OIDC and Keycloak Dev Services, and a few non-obvious tricks needed to make Swagger UI work correctly with Camel routes. Above all, I’d like to show you how easy it is to build and test a Camel and OIDC-based application using Quarkus.

Are you interested in other articles about Quarkus? In this blog post, you’ll find an introduction to Quarkus and Keycloak. Follow this link to read my latest article on Quarkus, which explains how to use MCP with the LangChain4j framework.

Do you want to deploy your Quarkus application on Kubernetes following best practices? Read my latest book, Hands-On Java with Kubernetes.

Source Code

Feel free to use my source code if you’d like to try it out yourself. To do that, you must clone my sample GitHub repository. The application source resides in the person-rest-api directory. Once you clone it, follow my instructions.

Maven Dependencies

The project uses Quarkus 3.36 and Java 25. Because Camel has its own BOM separate from Quarkus, you need to import both into dependencyManagement.

  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>io.quarkus.platform</groupId>
        <artifactId>quarkus-bom</artifactId>
        <version>3.36.2</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
      <dependency>
        <groupId>io.quarkus.platform</groupId>
        <artifactId>quarkus-camel-bom</artifactId>
        <version>3.36.2</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>

XML

We can split runtime dependencies into three groups. The Camel group covers the REST DSL and the HTTP transport, backed by Quarkus’s own Vert.x server, Jackson for JSON binding, the direct component for in-process routing, and the bean component to delegate to CDI beans.

  <dependency>
    <groupId>org.apache.camel.quarkus</groupId>
    <artifactId>camel-quarkus-rest</artifactId>
  </dependency>
  <dependency>
    <groupId>org.apache.camel.quarkus</groupId>
    <artifactId>camel-quarkus-platform-http</artifactId>
  </dependency>
  <dependency>
    <groupId>org.apache.camel.quarkus</groupId>
    <artifactId>camel-quarkus-jackson</artifactId>
  </dependency>
  <dependency>
    <groupId>org.apache.camel.quarkus</groupId>
    <artifactId>camel-quarkus-direct</artifactId>
  </dependency>
  <dependency>
    <groupId>org.apache.camel.quarkus</groupId>
    <artifactId>camel-quarkus-bean</artifactId>
  </dependency>

XML

The persistence group uses Hibernate ORM with Panache and an H2 in-memory database. Security uses quarkus-oidc, which automatically provisions a Keycloak container in dev mode. Finally, OpenAPI documentation requires both quarkus-smallrye-openapi and camel-quarkus-openapi-java. The reason for needing both is explained in the Swagger section below.

  <dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-hibernate-orm-panache</artifactId>
  </dependency>
  <dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-jdbc-h2</artifactId>
  </dependency>
  <dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-oidc</artifactId>
  </dependency>
  <dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-smallrye-openapi</artifactId>
  </dependency>
  <dependency>
    <groupId>org.apache.camel.quarkus</groupId>
    <artifactId>camel-quarkus-openapi-java</artifactId>
  </dependency>

XML

Data ORM Model with Quarkus Panache

The Person entity uses Quarkus Panache’s active record pattern. Because the PanacheEntity class already provides the id field and all CRUD methods as static calls on the entity class itself, the model is just field declarations.

  @Entity
  public class Person extends PanacheEntity {
      public String firstName;
      public String lastName;
      public String email;
      public int age;
      public String gender;
  }

Java

PersonService is a standard CDI bean. Because Camel invokes its methods via the bean component, you can use the @Header annotation directly on method parameters to pull path variables out of the Camel exchange without writing any routing logic.

  @ApplicationScoped
  public class PersonService {

      public List<Person> findAll() {
          return Person.listAll();
      }
      
      public Person findById(@Header("id") Long id) {
          return Person.findById(id);
      }

      @Transactional
      public Person create(Person person) {
          person.persist();
          return person;
      }

      @Transactional
      public Person update(@Header("id") Long id, Person person) {
          Person existing = Person.findById(id);
          if (existing == null) return null;
          existing.firstName = person.firstName;
          existing.lastName = person.lastName;
          existing.email = person.email;
          existing.age = person.age;
          existing.gender = person.gender;
          return existing;
      }

      @Transactional
      public void delete(@Header("id") Long id) {
          Person.deleteById(id);
      }
  }

Java

Camel Route with REST DSL

The ApiRoute class is the core of the application. It wires together HTTP endpoints, request/response logging, and the service bean calls.

  @ApplicationScoped
  public class ApiRoute extends RouteBuilder {

      @Inject
      PersonService personService;
  
      @Override
      public void configure() {

          interceptFrom()
                  .log(LoggingLevel.INFO, "pl.piomin.services.ApiRoute",
                          ">>> [${header.CamelHttpMethod}] ${header.CamelHttpUri} body=${body}");

          onCompletion()
                  .log(LoggingLevel.INFO, "pl.piomin.services.ApiRoute",
                          "<<< response body=${body}");

          restConfiguration()
                  .component("platform-http")
                  .bindingMode(RestBindingMode.json);

          rest("/persons")
                  .security("SecurityScheme")
                  .get().description("Get all persons").to("direct:getPersons")
                  .get("/{id}").description("Get person by id").to("direct:getPersonById")
                  .post().description("Create person").type(Person.class).to("direct:createPerson")
                  .put("/{id}").description("Update person").type(Person.class).to("direct:updatePerson")
                  .delete("/{id}").description("Delete person").to("direct:deletePerson");

          from("direct:getPersons").bean(personService, "findAll");
          from("direct:getPersonById").bean(personService, "findById");
          from("direct:createPerson").bean(personService, "create");
          from("direct:updatePerson").bean(personService, "update");
          from("direct:deletePerson").bean(personService, "delete");
      }
  }

Java

There are a few things worth pointing out here.

  1. The interceptFrom() method intercepts every incoming exchange before it reaches any route, so a single log statement covers all five endpoints without repeating it in each from() block.
  2. The restConfiguration().component("platform-http") line is critical for running in Quarkus. Because Quarkus already manages a Vert.x HTTP server, using the platform-http.
  3. Each REST operation uses the direct: component to fan out to a named in-process route. This indirection is intentional — it keeps the REST DSL declaration clean and makes each

The application protects all /persons* paths with an authenticated policy. To achieve this, we must add the following two properties to the application.properties file.

  quarkus.http.auth.permission.api.paths=/persons*
  quarkus.http.auth.permission.api.policy=authenticated

Plaintext

In dev mode, you do not need to install or configure Keycloak manually. Because quarkus-oidc is on the classpath, Quarkus Dev Services automatically starts a Keycloak container with a pre-configured realm and a client named quarkus-app. You only need to pin the port so the Swagger UI OAuth redirect URL stays predictable:

quarkus.keycloak.devservices.port=8180

Plaintext

When you start the application with mvn quarkus:dev Quarkus Dev UI is available at http://localhost:8080/q/dev-ui. It shows all active extensions, their configurations, and, in this application, the Camel route graph and the Keycloak realm details provisioned by Dev Services.

Go to the Keycloak provider in the OpenID Connect tile. Then, log in to the Keycloak instance running as a container on your machine. Use alice / alice credentials.

quarkus-camel-oidc

Then, you can test all your REST endpoints with an access token generated by Keycloak for a given user.

quarkus-camel-access-token

Integrate Quarkus Camel with Swagger OpenAPI

Getting Swagger UI to work correctly with Camel routes requires a specific configuration that is easy to get wrong. There are two separate OpenAPI integrations in this project, and each serves a different role. The camel-quarkus-openapi-java extension generates the OpenAPI spec from the Camel REST DSL. The quarkus-smallrye-openapi extension generates an OpenAPI spec from Quarkus REST endpoints. By default,  Quarkus SmallRye would not include any of the Camel-defined routes — it only sees JAX-RS resources. However, this method of generating Swagger has one key advantage over the Camel-based model. It recognizes Quarkus-specific dependencies, such as Quarkus OIDC, and accounts for them when generating the OpenAPI spec. So, you should explicitly enable Camel’s OpenAPI spec exposure to Quarkus SmallRye with the following property:

quarkus.camel.openapi.expose.enabled=true

Plaintext

That’s not all. After setting the property above, Quarkus merges the OpenAPI spec generated for Quarkus REST endpoints and the Camel REST DSL. So in this case, we must also include the quarkus-rest-jackson extension to the Maven dependencies to make it work. The .security("SecurityScheme") call in the route builder is the second non-obvious piece. This adds a security requirement to every operation in the generated spec. The name SecurityScheme is the default name generated by Quarkus SmallRye when detecting the OIDC module.

        rest("/persons")
                .security("SecurityScheme")
                .get()
                    .description("Get all persons")
                    .to("direct:getPersons")

Java

Now, you can go to http://localhost:8080/q/swagger-ui to see the OpenAPI spec for all your Camel REST endpoints. Then you can click the Authorize button to authenticate with Keycloak OIDC.

You can choose from several different authorization methods. In this case, use the alice user and the quarkus-app client.

Finally, you can call any of your endpoints using an automatically generated access token thanks to the integration between Quarkus SmallRye, Keycloak, and Apache Camel.

quarkus-camel-swagger-access-token

Conclusion

In this article, you saw how to use the Camel REST DSL with the platform-http component to register routes on the Quarkus server and integrate your app with Keycloak and Swagger. You learned how to build and test an app with Quarkus in developer mode and how to generate a complete OpenAPI spec that automatically integrates with OIDC.