Chapter 6. REST DSL
The REST DSL (Domain Specific Language) in Apache Camel provides a powerful way to define REST APIs. Kaoto offers multiple approaches to work with REST DSL, each suited for different workflows and preferences.
This guide demonstrates two distinct approaches to building REST APIs with Kaoto:
- API-First Approach- Link OpenAPI specifications at runtime
- Code-First Approach - Generate endpoints from OpenAPI using the REST Import Wizard or create endpoints manually from scratch using the visual REST Editor
Each approach builds a REST API that fetches books from Project Gutenberg via RapidAPI and generates AI-powered summaries using the Apache Camel OpenAI component.
6.1. Prerequisites Copy linkLink copied to clipboard!
Before starting any of the approaches, ensure you have:
- VS Code installed on your system - Follow the installation guide
- Kaoto VS Code extension - See the installation guide for setup instructions
- RapidAPI account and API key - Sign up at RapidAPI and subscribe to the Project Gutenberg Free Books API
- Ollama installed and running - Follow the Ollama installation guide to set it up
-
Granite 4 model pulled in Ollama - Run
ollama pull granite4:tiny-hin your terminal (Granite 4 on Ollama)) -
Camel catalog - This documentation was created with Camel version
4.18.0, though other versions and distributions are available on Apache Camel Catalog. Ensure you have the appropriate version of Camel installed and configured in your development environment.
6.1.2. Comparison of Approaches Copy linkLink copied to clipboard!
| Aspect | API-First | Code-First |
|---|---|---|
| Workflow | Link OpenAPI spec | Generate + Visual design |
| OpenAPI Usage | Runtime link (required) | Import wizard (not needed at runtime) or create from scratch |
| Best For | API contract enforcement | Learning and prototyping |
| UI Interaction | Minimal | Moderate |
| Examples |
|
|
6.1.3. Choose Your Approach Copy linkLink copied to clipboard!
6.1.3.1. 1. API-First Approach Copy linkLink copied to clipboard!
Best for: Teams with strict API contracts, when the OpenAPI spec is the source of truth, or when you need runtime flexibility to update the API by changing the spec.
What you’ll build: A REST endpoint that fetches book summaries from Project Gutenberg by linking an OpenAPI specification.
Key characteristic: The OpenAPI file must be present at runtime - Camel reads it to create endpoints. The OpenAPI file is the source of truth.
6.1.3.2. 2. Code-First Approach Copy linkLink copied to clipboard!
Best for: Rapid prototyping without OpenAPI available.
What you’ll build: The same REST endpoint as API-First, but with added AI-powered fun extracts using OpenAI, generated from the OpenAPI spec.
Key characteristic: OpenAPI can be used only during development - endpoints are generated into your route file or create from scratch. The Camel route file is the source of truth.
6.2. API-First Approach Copy linkLink copied to clipboard!
Link OpenAPI specifications to REST endpoints in Kaoto!
The API-first approach in Kaoto allows you to link an OpenAPI specification directly to your REST service. Instead of manually creating each endpoint, you reference the OpenAPI file and Apache Camel reads the specification at runtime to create all REST endpoints. The OpenAPI specification file must be kept with your integration as Camel needs it to run. Kaoto visualizes the direct route in the Design view.
OpenAPI vs OpenAI: OpenAPI (formerly known as Swagger) is an API specification standard and is not related to OpenAI (the company behind ChatGPT). The Apache Camel OpenAPI component works with OpenAPI specifications for REST API integration.
6.2.1. Creating the route file in Kaoto Copy linkLink copied to clipboard!
This can be done in two ways:
6.2.1.1. Linking the OpenAPI Specification Copy linkLink copied to clipboard!
This is the key step in the API-first approach.
- Click Rest in the top navigation, then Actions, and select + Add Service from the dropdown.
-
Add the
book-summary-api.openapi.yamlfile to your workspace at the same level as your route file. -
Click the pencil icon next to Open Api and enter the path to your OpenAPI file (e.g.,
book-summary-api.openapi.yaml). This adds the REST DSL block with the
openApi.specificationproperty:- rest: id: rest-1736 openApi: specification: book-summary-api.openapi.yaml
This is the API-first magic: By linking the OpenAPI specification, Apache Camel:
- Reads the OpenAPI file at runtime (the file must be present when running)
- Creates all REST endpoints defined in the specification
-
Maps operations to direct routes using
operationId - Builds the complete REST API structure from the specification
The specification path is relative to your workspace folder. The OpenAPI specification file (book-summary-api.openapi.yaml) must be kept with your integration - Camel needs it at runtime to create the REST endpoints. Make sure it’s in the same directory as your route file. Kaoto will validate the file path.
6.2.1.2. Implementing the direct route Copy linkLink copied to clipboard!
The OpenAPI specification uses the operationId property to map the operation to direct:getBookFunExtract. Now you’ll implement this direct route in Kaoto using the Design view to add steps visually.
- Replace the timer component: Click on the timer component and replace it with a Direct component.
-
Configure the direct endpoint: In Endpoint Properties > name, enter
getBookFunExtract Add removeHeaders processor: Insert a removeHeaders processor between the direct endpoint and the setBody processor.
-
Set the pattern to
CamelHttp* -
This removes all headers starting with
CamelHttpthat might interfere with the external API call
-
Set the pattern to
Add first setHeader processor: After removeHeaders, add a setHeader processor
-
Set name to
x-rapidapi-host - Change the expression type from Simple to Constant
-
Set expression to
project-gutenberg-free-books-api1.p.rapidapi.com - This sets the RapidAPI host header required by the Gutenberg API
-
Set name to
Add second setHeader processor: Add another setHeader processor
-
Set name to
x-rapidapi-key - Keep expression type as Simple
-
Set expression to
{{gutenberg.api.key}} -
Add your API key in the
application.propertiesfile in your workspace - This sets your API key using a property placeholder for security
-
Set name to
Add toD processor: Add a toD (dynamic to) processor
-
Set the uri to:
https://project-gutenberg-free-books-api1.p.rapidapi.com/books/${header.id}?bridgeEndpoint=true - This makes a dynamic HTTP call to the Gutenberg API using the book ID from the path parameter
-
Set the uri to:
Update setBody processor: Modify the setBody processor
- Change expression type to JSONPath
-
Set expression to
$.results[0].summary - This extracts the book summary from the JSON response
Update log processor: Modify the log processor
-
Set message to
Book summary: ${body} - This logs the book summary for debugging and verification
-
Set message to
6.2.2. Testing in Kaoto Copy linkLink copied to clipboard!
6.2.2.1. Running the Integration Copy linkLink copied to clipboard!
Before running your integration, you need to configure Kaoto’s run settings. Follow these steps carefully:
Step 1: Open VS Code Settings
Open VS Code Settings:
-
macOS: Press
Cmd + ,or go to Code > Preferences > Settings -
Windows/Linux: Press
Ctrl + ,or go to File > Preferences > Settings
-
macOS: Press
Click on the Workspace tab at the top of the settings window (not "User").
- This ensures settings only apply to this project.
-
Creates a
.vscode/settings.jsonfile in your project folder.
Step 2: Configure Kaoto Run Settings
-
In the search bar, type
kaototo filter Kaoto-related settings. Find and configure Kaoto: Run Arguments and Kaoto: Run Folder:
-
Add:
--management-port=8080 This sets a separate port for JBang management to avoid conflicts
-
Add:
Why Workspace-Level Settings Matter
Always configure Kaoto run settings at the workspace level (not globally):
- Global settings problem: Apply to all VS Code projects, meaning you can only run one integration at a time across all your projects
-
Workspace settings solution: Each project has its own isolated configuration in
.vscode/settings.json - Benefit: Run multiple integrations simultaneously in different workspaces without conflicts
- How to verify: Check that you clicked the "Workspace" tab in settings, not "User"
Step 3: Reload and Run
Reload VS Code: Press
Cmd/Ctrl + Shift + P, type "Reload Window", and press Enter.- This ensures VS Code picks up the new settings
Run the integration: In Kaoto, click the Run button in the folder.
-
Kaoto will start your integration using
JBang. You should see output in the terminal showing the integration starting up.
-
Kaoto will start your integration using
6.2.2.2. Testing through the Endpoint Copy linkLink copied to clipboard!
Open a terminal and run:
curl http://localhost:8080/books/1342/fun-extract- You should receive a JSON response with the book summary for "Pride and Prejudice" (book ID 1342).
6.2.2.3. Trying different books Copy linkLink copied to clipboard!
Test with other Project Gutenberg book IDs:
Frankenstein
curl http://localhost:8080/books/84/fun-extractThe Adventures of Sherlock Holmes
curl http://localhost:8080/books/1661/fun-extract
6.3. Code-First Approach Copy linkLink copied to clipboard!
Use Kaoto’s REST Import Wizard to generate endpoints and build routes visually!
The Code-first approach uses Kaoto’s REST Import Wizard to import OpenAPI specifications and automatically generate REST endpoints with route stubs. Unlike the API-first approach (which links the spec at runtime), the wizard creates explicit endpoint definitions in your route file. Once generated, the OpenAPI file is no longer needed - all endpoints are defined in your route file. You then implement the route logic visually using Kaoto’s component catalog and design view.
6.3.1. Importing OpenAPI specification with Kaoto Copy linkLink copied to clipboard!
6.3.1.1. Configuring the REST Import Wizard Copy linkLink copied to clipboard!
In the Kaoto extension, click in Import next to OpenAPI and it will open the REST Import Wizard.
- In the Kaoto Import Wizard, select Upload file as the source.
-
Click Choose file and select the
book-summary-api.openapi.yamlfile you downloaded in the previous section. The wizard will parse the file and show all discovered operations.
-
You should see the
GET /books/{id}/fun-extractoperation listed. Configure the following options (both should be checked):
- Create REST DSL operations - Generates REST endpoint definitions
Create routes with direct endpoints - Generates route stubs for each operation
Choose the folder to save the information and then give a name to the route.
6.3.1.2. Reviewing generated structure in Kaoto Copy linkLink copied to clipboard!
After importing, Kaoto generates and displays in the Design view:
- REST DSL definition - Complete endpoint with parameters and responses
- Direct route stub - A placeholder route ready for implementation
The generated structure looks like this:
Your route file now contains the REST endpoint definition, and the direct route stub.
6.3.2. Implementing the route visually in Kaoto Copy linkLink copied to clipboard!
Now you’ll implement the logic by reusing the route from the API-first approach and adding OpenAI integration.
This section assumes you’ve completed the API-First Approach documentation example. If not, complete that first or refer to it for the Gutenberg API integration steps.
6.3.2.1. Copying route from API-first implementation Copy linkLink copied to clipboard!
-
Open the route file from the API-first documentation example (e.g.,
book-api.camel.yaml) -
In Kaoto’s Design view, locate the
route-getBookFunExtractroute Right-click on the route (not on individual steps) and select Copy
6.3.2.2. Pasting route into Code-first route Copy linkLink copied to clipboard!
- Switch back to your code-first route file
-
In the Design view, find the
route-getBookFunExtractroute Right-click on the Design canvas itself (not on the setBody step) and select Paste. This pastes the complete route from the API-first route.
6.3.2.3. Drag and drop steps to reorder Copy linkLink copied to clipboard!
-
In the Design view, locate the
removeHeadersstep -
Click and drag the
removeHeadersstep -
Drop it directly after the
directcomponent (at the beginning of the route) - Do the same with the other components.
The new route structure after drag and drop:
6.3.2.4. Deleting placeholder and extra steps Copy linkLink copied to clipboard!
-
Delete the placeholder
setBodystep at the end (the one with "Operation getBookFunExtract not yet implemented") -
Delete any remaining copied
directcomponent
Your route now has the complete Gutenberg API integration in the correct order.
6.3.2.5. Adding OpenAI integration from catalog Copy linkLink copied to clipboard!
Now add the AI-powered fun extract generation:
-
Hover over the arrow after the
setBodystep (the one that extracts$.results[0].summary) - Click the + button that appears
-
In the catalog search, type
openai - Select OpenAI component
Configure in Kaoto’s form:
Property Value Operation
chat-completion
Api Key
OLLAMA-LOCAL-KEY
Base Url
Model
granite4:tiny-h
System Message
Summarize this text into a couple of short sentences and give it a funny twist
This sends the book summary to your local
Ollamainstance running theGranite 4model for AI-powered fun extracts.Note- For more details on configuring OpenAI in Kaoto, refer to the Quickstart guide.
-
The OpenAI component is now inserted between
setBodyandlog, completing your route.
Complete Route
Your final route should look like this:
6.3.3. Testing in Kaoto Copy linkLink copied to clipboard!
6.3.3.1. Running the Integration Copy linkLink copied to clipboard!
-
Make sure
Ollamais running with the Granite 4 model - In Kaoto’s toolbar, click the Run button. Make sure your application.properties and the new route are in the same folder.
- Kaoto will start your integration using JBang
- Watch the Design view to see your routes activate
6.3.3.2. Testing through the endpoint Copy linkLink copied to clipboard!
Open a terminal and run:
curl http://localhost:8080/books/1342/fun-extract
You should receive an AI-generated fun extract of "Pride and Prejudice" (book ID 1342).
6.3.3.3. Trying different books Copy linkLink copied to clipboard!
Frankenstein
curl http://localhost:8080/books/84/fun-extractThe Adventures of Sherlock Holmes
curl http://localhost:8080/books/1661/fun-extract
Each request will return a unique AI-generated fun extract!
6.4. Extending with REST Editor Copy linkLink copied to clipboard!
Use Kaoto’s REST Editor to visually add and manage REST endpoints from scratch!
Kaoto’s REST Editor provides a visual tree-based interface for creating and managing REST endpoints from scratch in your Camel integrations. Unlike the code-first approach (which generates endpoints from OpenAPI) or API-first (which links a spec at runtime), the REST Editor lets you manually create, configure, and manage individual endpoints through a visual interface without any OpenAPI specification. This approach is ideal for building REST APIs from scratch, extending existing REST APIs, and maintaining your API structure over time.
This example extends the REST API from the Code-First Approach. You can either:
- Continue from your existing route file, or
- Copy the final route from that document.
6.4.1. Opening Kaoto’s REST editor Copy linkLink copied to clipboard!
This can be done in two ways:
6.4.1.1. Opening route file in Kaoto Copy linkLink copied to clipboard!
-
In VS Code, open the route file from Part 2 (e.g.,
rest-api.camel.yaml) - Kaoto will automatically open, showing the Canvas view
6.4.1.2. Accessing the REST Editor Copy linkLink copied to clipboard!
- In the Kaoto toolbar, click the REST DSL button
Kaoto’s REST Editor will open, displaying your REST structure in a tree view
You should see in the tree:
- Your REST service
-
The existing
GET /books/{id}/fun-extractendpoint - The associated direct route
6.4.2. Adding a new endpoint using Kaoto’s REST editor Copy linkLink copied to clipboard!
Now, use Kaoto’s REST Editor to add a new endpoint for searching popular books.
6.4.2.1. Adding the GET Operation Copy linkLink copied to clipboard!
Since the new endpoint shares the same base path (/books), we’ll add it to the existing REST block.
When to Create a New REST Block
Create a new REST block (using Actions Add REST at the top level) when you need:
-
A different base path (e.g.,
/authorsinstead of/books) - To organize endpoints by domain or feature area
For this example, both endpoints use /books/* paths, so we add the operation to the existing REST block.
- In the REST block in the tree, click Actions
- Select Add Operation
In Kaoto’s modal dialog, configure:
Property Value HTTP Method
GETPath
/books/popularOperation ID
listBooksClick Add to create the operation in the tree.
6.4.2.2. Configuring the operation in Kaoto’s form Copy linkLink copied to clipboard!
With the new operation selected in the tree, configure its properties using Kaoto’s form:
| Property | Value |
|---|---|
| Produces |
|
| Description | Lists popular books from Project Gutenberg |
6.4.2.3. Adding response messages using the form Copy linkLink copied to clipboard!
Scroll down in Kaoto’s configuration form and add response messages:
- Click + next to Response Message
Configure the first response in the form:
- Code: 200
- Message: Books retrieved successfully
- Content Type: application/json
- Add a new response again
Configure the error response:
- Code: 500
- Message: Server error during processing
Current state of the route file:
- rest: id: rest-1775038763756 get: - id: getBookFunExtract path: /books/{id}/fun-extract routeId: route-getBookFunExtract to: direct:getBookFunExtract description: Fetches a book from Project Gutenberg and generates an AI extract using OpenAI produces: application/json param: - name: id type: path required: true description: Project Gutenberg book ID (e.g., 11 for Alice's Adventures in Wonderland) dataType: integer responseMessage: - code: "200" message: Book fun extract generated successfully contentType: application/json - code: "404" message: Book not found in Project Gutenberg - code: "500" message: Server error during processing - id: listBooks path: /books/popular to: uri: direct parameters: name: direct-listBooks produces: application/json description: Lists popular books from Project Gutenberg responseMessage: - message: Server error during processing code: "500" - message: Books retrieved successfully code: "200" contentType: application/json - route: id: route-getBookFunExtract from: uri: direct:getBookFunExtract id: direct-from-getBookFunExtract steps: - removeHeaders: id: removeHeaders-4268-1881 pattern: CamelHttp* - setHeader: id: setHeader-3265-3267 name: x-rapidapi-host constant: expression: project-gutenberg-free-books-api1.p.rapidapi.com - setHeader: id: setHeader-2139-3021 simple: expression: "{{gutenberg.api.key}}" name: x-rapidapi-key - toD: id: toD-4177-4046 uri: https://project-gutenberg-free-books-api1.p.rapidapi.com/books/${header.id}?bridgeEndpoint=true parameters: {} - setBody: id: setBody-2130-2169 jsonpath: expression: $.results[0].summary - to: id: to-3162 uri: openai parameters: operation: chat-completion apiKey: OLLAMA-LOCAL-KEY baseUrl: http://localhost:11434/v1 model: granite4:tiny-h systemMessage: Summarize this text into a couple of short sentences and give it a funny twist - log: message: '"Book summary: ${body}"'
6.4.2.4. Creating the direct route Copy linkLink copied to clipboard!
- Next to Endpoint Name in Kaoto’s form, you’ll see a Create Route button
- Click Create Route
Kaoto will generate a new direct route stub for
direct:listBooksand show it in the Canvas
6.4.3. Implementing the popular books route in Kaoto Copy linkLink copied to clipboard!
Now, implement the logic using Kaoto’s Canvas view.
6.4.3.2. Reusing steps from the existing route Copy linkLink copied to clipboard!
Since both routes call the same RapidAPI service, you can duplicate the common steps from the existing route:
-
Navigate to the
route-getBookFunExtractroute in Canvas -
Select the
removeHeadersstep Right-click over the component and select Duplicate
-
Drag the duplicated step to the
route-listBooksroute and drop it after thedirectcomponent -
Repeat for both
setHeadersteps (x-rapidapi-hostandx-rapidapi-key)
This approach saves time by reusing the exact configuration from the working route.
6.4.3.3. Adding HTTP call from Catalog Copy linkLink copied to clipboard!
- Click Add step in the Canvas
-
Search for
toin the catalog (nottoD- we don’t need dynamic URI here) - Select To
-
Configure: URI =
https://project-gutenberg-free-books-api1.p.rapidapi.com/books?bridgeEndpoint=true
This calls the Gutenberg API to get a list of popular books.
6.4.3.4. Extracting book information Copy linkLink copied to clipboard!
- Click Add step in the Canvas
-
Search for
setBodyin the catalog - Select Set Body
Configure:
-
Expression Type:
JSONPath -
Expression:
$.results[*].['title', 'authors']
-
Expression Type:
This extracts just the title and authors from each book in the response.
6.4.3.5. Formatting as Pretty JSON Copy linkLink copied to clipboard!
- Click Add step in the Canvas
-
Search for
marshalin the catalog - Select Marshal
- Select JSON as the data format
-
Enable Pretty Print:
true
This formats the response as readable JSON.
6.4.3.6. Adding Log Copy linkLink copied to clipboard!
- Click Add step in the Canvas
-
Search for
login the catalog - Select Logger
-
Configure: Message =
Books list: ${body}Complete Route
Your final route file should now have one REST block with two operations and two routes:
6.4.4. Testing the new endpoint Copy linkLink copied to clipboard!
6.4.4.1. Running the Integration Copy linkLink copied to clipboard!
-
Ensure your
application.propertiesfile has your RapidAPI key - In Kaoto, click the Run: folder button in the folder
-
Kaoto will start your integration using
JBang
6.4.4.2. Testing the popular books endpoint Copy linkLink copied to clipboard!
curl http://localhost:8080/books/popular
You should receive a JSON array with popular books, showing their titles and authors:
[
{
"title": "Frankenstein; or, the modern prometheus",
"authors": [
{
"id": 3761,
"name": "Shelley, Mary Wollstonecraft"
}
]
},
{
"title": "The City of God, Volume I",
"authors": [
{
"id": 18428,
"name": "Augustine, Saint, Bishop of Hippo"
},
{
"id": 1101993,
"name": "Augustine, of Hippo, Saint"
}
]
},
{
"title": "Wuthering Heights",
"authors": [
{
"id": 151,
"name": "Brontë, Emily"
}
]
}
// ... more books
]