From Database to REST API in 5 Minutes with Quarkus and Camel
Skip the boilerplate and see how Quarkus Dev Services and Apache Camel let you expose database data as a REST API with just one route.
Ever had valuable data locked away in a database, waiting to be exposed as a modern REST API? Normally, you’d set up a database, configure connection pools, write a controller, a service, a repository, and all the boilerplate that comes with it. That takes hours, not minutes.
What if you could skip all that and get a functional API running in under five minutes?
That’s exactly what we’ll do today. We’ll combine Quarkus for its blazing-fast startup and developer experience with Apache Camel for its elegant integration logic. You’ll see how Quarkus Dev Services can spin up a PostgreSQL database automatically, and how a single Camel route can bridge that database to a REST endpoint.
This tutorial is for Java developers who want to see just how far developer productivity has come. Let’s code!
Bootstrap the Project
You’ll need:
JDK 17 or newer
Maven 3.8+
Podman or Docker (for Dev Services containers)
mvn io.quarkus:quarkus-maven-plugin:create \
-DprojectGroupId=org.acme \
-DprojectArtifactId=camel-rest-sql \
-Dextensions="camel-quarkus-platform-http,camel-quarkus-jackson,camel-quarkus-sql,quarkus-jdbc-postgresql"
What we just pulled in:
camel-quarkus-platform-http
: lets Camel expose HTTP endpoints.camel-quarkus-sql
: lets Camel query databases using SQL.quarkus-jdbc-postgresql
: PostgreSQL driver for Quarkus.
Move into the project directory:
cd camel-rest-sql
Seed the Database
Quarkus Dev Services will start PostgreSQL for you automatically in dev mode. Unfortunately, the easy way to populate it with Hibernate isn’t working for standalone JDBC. So we are going to just seed it programatically. A nice reminder how much boilerplate this usually would be.
Create src/main/java/org/acme/DatabaseSeeder.java
:
// src/main/java/org/acme/DatabaseSeeder.java
package org.acme;
import java.sql.Connection;
import java.sql.Statement;
import javax.sql.DataSource;
import io.quarkus.runtime.Startup;
import jakarta.annotation.PostConstruct;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
@Startup
@ApplicationScoped
public class DatabaseSeeder {
@Inject
DataSource dataSource; // Inject the datasource configured by Quarkus
@PostConstruct
void setupDb() {
try (Connection connection = dataSource.getConnection();
Statement statement = connection.createStatement()) {
// Drop table if it exists and create a new one
statement.execute("DROP TABLE IF EXISTS users;");
statement.execute("""
CREATE TABLE users (
id SERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
city VARCHAR(255)
);
""");
// Insert initial data
statement.execute("""
INSERT INTO users (name, city) VALUES
('Alice', 'Amsterdam'),
('Bob', 'Berlin'),
('Carol', 'Copenhagen');
""");
} catch (Exception e) {
// In a real application, you'd handle this exception properly
throw new RuntimeException("Could not initialize database", e);
}
}
}
Quarkus will start the DB with its Dev Service feature.
Define the Camel Route
Now for the magic. Camel routes describe how messages flow through your system. We’ll create one that listens for HTTP requests and queries our database.
Create src/main/java/org/acme/UserApiRoute.java
:
package org.acme;
package org.acme;
import org.apache.camel.builder.RouteBuilder;
import jakarta.enterprise.context.ApplicationScoped;
@ApplicationScoped
public class UserApiRoute extends RouteBuilder {
@Override
public void configure() {
from("platform-http:/users?httpMethodRestrict=GET")
.to("sql:select * from users")
.marshal().json();
}
}
How it works:
from("platform-http:/users?httpMethodRestrict=GET")
→ handles GET requests to/users
..to("sql:select * from users")
→ runs the SQL query against the Dev Services PostgreSQL instance..marshal().json()
→ turns the result set into JSON.
That’s a complete REST API, in one route.
Run It
Start Quarkus in dev mode:
./mvnw quarkus:dev
Watch the logs for:
INFO [io.qua.dev.postgresql] (Quarkus Main Thread) Dev Services for PostgreSQL started.
Quarkus noticed the PostgreSQL extension and launched a container automatically, running your import.sql
.
Now, test the API:
curl http://localhost:8080/users
You’ll see:
[
{
"id": 1,
"name": "Alice",
"city": "Amsterdam"
},
{
"id": 2,
"name": "Bob",
"city": "Berlin"
},
{
"id": 3,
"name": "Carol",
"city": "Copenhagen"
}
]
Zero manual setup. One route. Working API.
Hot Reload in Action
Keep Quarkus running. Now tweak the route to change the query. Edit UserApiRoute.java
:
from("platform-http:/users?httpMethodRestrict=GET")
.to("sql:select name, city from users order by name")
.marshal().json();
Save the file. Quarkus will reload instantly. Refresh your browser:
[
{
"name": "Alice",
"city": "Amsterdam"
},
{
"name": "Bob",
"city": "Berlin"
},
{
"name": "Carol",
"city": "Copenhagen"
}
]
No restart. No redeploy. Just save and refresh.
Why This Matters
In enterprise projects, database APIs are often the first integration point. Traditionally, that means scaffolding controllers, services, repositories, configuration files, and test data. With Quarkus + Camel:
Database setup: automated by Dev Services.
REST mapping: one Camel route.
Reload cycle: instant.
This radically shortens iteration time. Your team can try ideas in minutes, not days.
Next Steps
You’ve only scratched the surface. Camel has over 300 components: Kafka, JMS, AWS, Salesforce, Twitter, you name it. Combine them with Quarkus for a fast, cloud-native developer experience.
References:
Happy coding.