This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/main by this push:
     new 07dc1f1e046 CAMEL-18057: rest-dsl - Combine rest and linked route 
together as single route
07dc1f1e046 is described below

commit 07dc1f1e046a74d9c144c794b226f4f4c79c2f4f
Author: Claus Ibsen <claus.ib...@gmail.com>
AuthorDate: Fri Sep 23 17:20:15 2022 +0200

    CAMEL-18057: rest-dsl - Combine rest and linked route together as single 
route
---
 .../org/apache/camel/spi/RestConfiguration.java    | 19 ++++++
 .../camel/impl/RestConfigurationConfigurer.java    |  6 ++
 .../java/org/apache/camel/impl/DefaultModel.java   | 44 ++++++++++++++
 .../org/apache/camel/model/rest/delete.json        |  1 +
 .../resources/org/apache/camel/model/rest/get.json |  1 +
 .../org/apache/camel/model/rest/head.json          |  1 +
 .../org/apache/camel/model/rest/patch.json         |  1 +
 .../org/apache/camel/model/rest/post.json          |  1 +
 .../resources/org/apache/camel/model/rest/put.json |  1 +
 .../apache/camel/model/rest/restConfiguration.json |  1 +
 .../model/rest/RestConfigurationDefinition.java    | 39 ++++++++++++
 .../apache/camel/model/rest/RestDefinition.java    | 34 ++++++++++-
 .../apache/camel/model/rest/VerbDefinition.java    | 14 +++++
 .../component/rest/FromRestInlineRoutesTest.java   | 69 ++++++++++++++++++++++
 .../camel/component/rest/FromRestRouteIdTest.java  | 64 ++++++++++++++++++++
 .../RestConfigurationPropertiesConfigurer.java     |  6 ++
 .../camel-main-configuration-metadata.json         |  1 +
 core/camel-main/src/main/docs/main.adoc            |  3 +-
 .../camel/main/RestConfigurationProperties.java    | 15 +++++
 .../java/org/apache/camel/xml/in/ModelParser.java  |  2 +
 docs/user-manual/modules/ROOT/pages/rest-dsl.adoc  | 58 +++++++++++++++++-
 21 files changed, 376 insertions(+), 5 deletions(-)

diff --git 
a/core/camel-api/src/main/java/org/apache/camel/spi/RestConfiguration.java 
b/core/camel-api/src/main/java/org/apache/camel/spi/RestConfiguration.java
index 7de9c03a52d..1750f6710ee 100644
--- a/core/camel-api/src/main/java/org/apache/camel/spi/RestConfiguration.java
+++ b/core/camel-api/src/main/java/org/apache/camel/spi/RestConfiguration.java
@@ -64,6 +64,7 @@ public class RestConfiguration {
     private RestBindingMode bindingMode = RestBindingMode.off;
     private boolean skipBindingOnErrorCode = true;
     private boolean clientRequestValidation;
+    private boolean inlineRoutes;
     private boolean enableCORS;
     private String jsonDataFormat;
     private String xmlDataFormat;
@@ -402,6 +403,24 @@ public class RestConfiguration {
         this.enableCORS = enableCORS;
     }
 
+    public boolean isInlineRoutes() {
+        return inlineRoutes;
+    }
+
+    /**
+     * Inline routes in rest-dsl which are linked using direct endpoints.
+     *
+     * By default, each service in Rest DSL is an individual route, meaning 
that you would
+     * have at least two routes per service (rest-dsl, and the route linked 
from rest-dsl).
+     * Enabling this allows Camel to optimize and inline this as a single 
route, however
+     * this requires to use direct endpoints, which must be unique per service.
+     *
+     * This option is default <tt>false</tt>.
+     */
+    public void setInlineRoutes(boolean inlineRoutes) {
+        this.inlineRoutes = inlineRoutes;
+    }
+
     /**
      * Gets the name of the json data format.
      * <p/>
diff --git 
a/core/camel-core-engine/src/generated/java/org/apache/camel/impl/RestConfigurationConfigurer.java
 
b/core/camel-core-engine/src/generated/java/org/apache/camel/impl/RestConfigurationConfigurer.java
index fa275642012..e79d85bc2a1 100644
--- 
a/core/camel-core-engine/src/generated/java/org/apache/camel/impl/RestConfigurationConfigurer.java
+++ 
b/core/camel-core-engine/src/generated/java/org/apache/camel/impl/RestConfigurationConfigurer.java
@@ -55,6 +55,8 @@ public class RestConfigurationConfigurer extends 
org.apache.camel.support.compon
         case "Host": target.setHost(property(camelContext, 
java.lang.String.class, value)); return true;
         case "hostnameresolver":
         case "HostNameResolver": 
target.setHostNameResolver(property(camelContext, java.lang.String.class, 
value)); return true;
+        case "inlineroutes":
+        case "InlineRoutes": target.setInlineRoutes(property(camelContext, 
boolean.class, value)); return true;
         case "jsondataformat":
         case "JsonDataFormat": target.setJsonDataFormat(property(camelContext, 
java.lang.String.class, value)); return true;
         case "port":
@@ -112,6 +114,8 @@ public class RestConfigurationConfigurer extends 
org.apache.camel.support.compon
         case "Host": return java.lang.String.class;
         case "hostnameresolver":
         case "HostNameResolver": return java.lang.String.class;
+        case "inlineroutes":
+        case "InlineRoutes": return boolean.class;
         case "jsondataformat":
         case "JsonDataFormat": return java.lang.String.class;
         case "port":
@@ -170,6 +174,8 @@ public class RestConfigurationConfigurer extends 
org.apache.camel.support.compon
         case "Host": return target.getHost();
         case "hostnameresolver":
         case "HostNameResolver": return target.getHostNameResolver();
+        case "inlineroutes":
+        case "InlineRoutes": return target.isInlineRoutes();
         case "jsondataformat":
         case "JsonDataFormat": return target.getJsonDataFormat();
         case "port":
diff --git 
a/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultModel.java 
b/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultModel.java
index 477b67a62fa..d71893ccc87 100644
--- 
a/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultModel.java
+++ 
b/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultModel.java
@@ -40,6 +40,7 @@ import org.apache.camel.model.BeanFactoryDefinition;
 import org.apache.camel.model.DataFormatDefinition;
 import org.apache.camel.model.DefaultRouteTemplateContext;
 import org.apache.camel.model.FaultToleranceConfigurationDefinition;
+import org.apache.camel.model.FromDefinition;
 import org.apache.camel.model.Model;
 import org.apache.camel.model.ModelCamelContext;
 import org.apache.camel.model.ModelLifecycleStrategy;
@@ -57,6 +58,7 @@ import org.apache.camel.model.RoutesDefinition;
 import org.apache.camel.model.TemplatedRouteBeanDefinition;
 import org.apache.camel.model.TemplatedRouteDefinition;
 import org.apache.camel.model.TemplatedRouteParameterDefinition;
+import org.apache.camel.model.ToDefinition;
 import org.apache.camel.model.cloud.ServiceCallConfigurationDefinition;
 import org.apache.camel.model.rest.RestDefinition;
 import org.apache.camel.model.transformer.TransformerDefinition;
@@ -178,6 +180,48 @@ public class DefaultModel implements Model {
 
         removeRouteDefinitions(list);
 
+
+        // special if rest-dsl is inlining routes
+        if (camelContext.getRestConfiguration().isInlineRoutes()) {
+            List<RouteDefinition> allRoutes = new ArrayList<>();
+            allRoutes.addAll(list);
+            allRoutes.addAll(this.routeDefinitions);
+
+            List<RouteDefinition> toBeRemoved = new ArrayList<>();
+            Map<String, RouteDefinition> directs = new HashMap<>();
+            for (RouteDefinition r : allRoutes) {
+                // does the route start with direct, which is candidate for 
rest-dsl
+                FromDefinition from = r.getInput();
+                if (from != null) {
+                    String uri = from.getEndpointUri();
+                    if (uri != null && uri.startsWith("direct:")) {
+                        directs.put(uri, r);
+                    }
+                }
+            }
+            for (RouteDefinition r : allRoutes) {
+                // loop all rest routes
+                FromDefinition from = r.getInput();
+                if (from != null) {
+                    String uri = from.getEndpointUri();
+                    if (uri != null && uri.startsWith("rest:")) {
+                        ToDefinition to = (ToDefinition) r.getOutputs().get(0);
+                        String toUri = to.getEndpointUri();
+                        RouteDefinition toBeInlined = directs.get(toUri);
+                        if (toBeInlined != null) {
+                            toBeRemoved.add(toBeInlined);
+                            // inline by replacing the outputs
+                            r.getOutputs().clear();
+                            r.getOutputs().addAll(toBeInlined.getOutputs());
+                        }
+                    }
+                }
+            }
+            // remove all the routes that was inlined
+            list.removeAll(toBeRemoved);
+            this.routeDefinitions.removeAll(toBeRemoved);
+        }
+
         for (RouteDefinition r : list) {
             for (ModelLifecycleStrategy s : modelLifecycleStrategies) {
                 s.onAddRouteDefinition(r);
diff --git 
a/core/camel-core-model/src/generated/resources/org/apache/camel/model/rest/delete.json
 
b/core/camel-core-model/src/generated/resources/org/apache/camel/model/rest/delete.json
index 0a0900f2164..66f60b9b4e2 100644
--- 
a/core/camel-core-model/src/generated/resources/org/apache/camel/model/rest/delete.json
+++ 
b/core/camel-core-model/src/generated/resources/org/apache/camel/model/rest/delete.json
@@ -24,6 +24,7 @@
     "enableCORS": { "kind": "attribute", "displayName": "Enable CORS", 
"label": "advanced", "required": false, "type": "boolean", "javaType": 
"java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "Whether to enable CORS headers in the 
HTTP response. This option will override what may be configured on a parent 
level The default value is false." },
     "apiDocs": { "kind": "attribute", "displayName": "Api Docs", "label": 
"advanced", "required": false, "type": "boolean", "javaType": 
"java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": true, "description": "Whether to include or exclude this rest 
operation in API documentation. The default value is true." },
     "deprecated": { "kind": "attribute", "displayName": "Deprecated", "label": 
"advanced", "required": false, "type": "boolean", "javaType": 
"java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "Marks this rest operation as deprecated 
in OpenApi documentation." },
+    "routeId": { "kind": "attribute", "displayName": "Route Id", "required": 
false, "type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "description": "Sets the id of the route" 
},
     "id": { "kind": "attribute", "displayName": "Id", "required": false, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "description": "Sets the id of this node" 
},
     "description": { "kind": "element", "displayName": "Description", 
"required": false, "type": "object", "javaType": 
"org.apache.camel.model.DescriptionDefinition", "deprecated": false, 
"autowired": false, "secret": false, "description": "Sets the description of 
this node" }
   }
diff --git 
a/core/camel-core-model/src/generated/resources/org/apache/camel/model/rest/get.json
 
b/core/camel-core-model/src/generated/resources/org/apache/camel/model/rest/get.json
index f4474a62ee9..366df91903a 100644
--- 
a/core/camel-core-model/src/generated/resources/org/apache/camel/model/rest/get.json
+++ 
b/core/camel-core-model/src/generated/resources/org/apache/camel/model/rest/get.json
@@ -24,6 +24,7 @@
     "enableCORS": { "kind": "attribute", "displayName": "Enable CORS", 
"label": "advanced", "required": false, "type": "boolean", "javaType": 
"java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "Whether to enable CORS headers in the 
HTTP response. This option will override what may be configured on a parent 
level The default value is false." },
     "apiDocs": { "kind": "attribute", "displayName": "Api Docs", "label": 
"advanced", "required": false, "type": "boolean", "javaType": 
"java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": true, "description": "Whether to include or exclude this rest 
operation in API documentation. The default value is true." },
     "deprecated": { "kind": "attribute", "displayName": "Deprecated", "label": 
"advanced", "required": false, "type": "boolean", "javaType": 
"java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "Marks this rest operation as deprecated 
in OpenApi documentation." },
+    "routeId": { "kind": "attribute", "displayName": "Route Id", "required": 
false, "type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "description": "Sets the id of the route" 
},
     "id": { "kind": "attribute", "displayName": "Id", "required": false, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "description": "Sets the id of this node" 
},
     "description": { "kind": "element", "displayName": "Description", 
"required": false, "type": "object", "javaType": 
"org.apache.camel.model.DescriptionDefinition", "deprecated": false, 
"autowired": false, "secret": false, "description": "Sets the description of 
this node" }
   }
diff --git 
a/core/camel-core-model/src/generated/resources/org/apache/camel/model/rest/head.json
 
b/core/camel-core-model/src/generated/resources/org/apache/camel/model/rest/head.json
index cfd75e821c1..af317c58e3d 100644
--- 
a/core/camel-core-model/src/generated/resources/org/apache/camel/model/rest/head.json
+++ 
b/core/camel-core-model/src/generated/resources/org/apache/camel/model/rest/head.json
@@ -24,6 +24,7 @@
     "enableCORS": { "kind": "attribute", "displayName": "Enable CORS", 
"label": "advanced", "required": false, "type": "boolean", "javaType": 
"java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "Whether to enable CORS headers in the 
HTTP response. This option will override what may be configured on a parent 
level The default value is false." },
     "apiDocs": { "kind": "attribute", "displayName": "Api Docs", "label": 
"advanced", "required": false, "type": "boolean", "javaType": 
"java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": true, "description": "Whether to include or exclude this rest 
operation in API documentation. The default value is true." },
     "deprecated": { "kind": "attribute", "displayName": "Deprecated", "label": 
"advanced", "required": false, "type": "boolean", "javaType": 
"java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "Marks this rest operation as deprecated 
in OpenApi documentation." },
+    "routeId": { "kind": "attribute", "displayName": "Route Id", "required": 
false, "type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "description": "Sets the id of the route" 
},
     "id": { "kind": "attribute", "displayName": "Id", "required": false, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "description": "Sets the id of this node" 
},
     "description": { "kind": "element", "displayName": "Description", 
"required": false, "type": "object", "javaType": 
"org.apache.camel.model.DescriptionDefinition", "deprecated": false, 
"autowired": false, "secret": false, "description": "Sets the description of 
this node" }
   }
diff --git 
a/core/camel-core-model/src/generated/resources/org/apache/camel/model/rest/patch.json
 
b/core/camel-core-model/src/generated/resources/org/apache/camel/model/rest/patch.json
index 729090cfd93..c013951b98f 100644
--- 
a/core/camel-core-model/src/generated/resources/org/apache/camel/model/rest/patch.json
+++ 
b/core/camel-core-model/src/generated/resources/org/apache/camel/model/rest/patch.json
@@ -24,6 +24,7 @@
     "enableCORS": { "kind": "attribute", "displayName": "Enable CORS", 
"label": "advanced", "required": false, "type": "boolean", "javaType": 
"java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "Whether to enable CORS headers in the 
HTTP response. This option will override what may be configured on a parent 
level The default value is false." },
     "apiDocs": { "kind": "attribute", "displayName": "Api Docs", "label": 
"advanced", "required": false, "type": "boolean", "javaType": 
"java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": true, "description": "Whether to include or exclude this rest 
operation in API documentation. The default value is true." },
     "deprecated": { "kind": "attribute", "displayName": "Deprecated", "label": 
"advanced", "required": false, "type": "boolean", "javaType": 
"java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "Marks this rest operation as deprecated 
in OpenApi documentation." },
+    "routeId": { "kind": "attribute", "displayName": "Route Id", "required": 
false, "type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "description": "Sets the id of the route" 
},
     "id": { "kind": "attribute", "displayName": "Id", "required": false, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "description": "Sets the id of this node" 
},
     "description": { "kind": "element", "displayName": "Description", 
"required": false, "type": "object", "javaType": 
"org.apache.camel.model.DescriptionDefinition", "deprecated": false, 
"autowired": false, "secret": false, "description": "Sets the description of 
this node" }
   }
diff --git 
a/core/camel-core-model/src/generated/resources/org/apache/camel/model/rest/post.json
 
b/core/camel-core-model/src/generated/resources/org/apache/camel/model/rest/post.json
index 29ca52ed641..8dbaaa36c1e 100644
--- 
a/core/camel-core-model/src/generated/resources/org/apache/camel/model/rest/post.json
+++ 
b/core/camel-core-model/src/generated/resources/org/apache/camel/model/rest/post.json
@@ -24,6 +24,7 @@
     "enableCORS": { "kind": "attribute", "displayName": "Enable CORS", 
"label": "advanced", "required": false, "type": "boolean", "javaType": 
"java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "Whether to enable CORS headers in the 
HTTP response. This option will override what may be configured on a parent 
level The default value is false." },
     "apiDocs": { "kind": "attribute", "displayName": "Api Docs", "label": 
"advanced", "required": false, "type": "boolean", "javaType": 
"java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": true, "description": "Whether to include or exclude this rest 
operation in API documentation. The default value is true." },
     "deprecated": { "kind": "attribute", "displayName": "Deprecated", "label": 
"advanced", "required": false, "type": "boolean", "javaType": 
"java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "Marks this rest operation as deprecated 
in OpenApi documentation." },
+    "routeId": { "kind": "attribute", "displayName": "Route Id", "required": 
false, "type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "description": "Sets the id of the route" 
},
     "id": { "kind": "attribute", "displayName": "Id", "required": false, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "description": "Sets the id of this node" 
},
     "description": { "kind": "element", "displayName": "Description", 
"required": false, "type": "object", "javaType": 
"org.apache.camel.model.DescriptionDefinition", "deprecated": false, 
"autowired": false, "secret": false, "description": "Sets the description of 
this node" }
   }
diff --git 
a/core/camel-core-model/src/generated/resources/org/apache/camel/model/rest/put.json
 
b/core/camel-core-model/src/generated/resources/org/apache/camel/model/rest/put.json
index bd9a5d8607f..728d0d886f6 100644
--- 
a/core/camel-core-model/src/generated/resources/org/apache/camel/model/rest/put.json
+++ 
b/core/camel-core-model/src/generated/resources/org/apache/camel/model/rest/put.json
@@ -24,6 +24,7 @@
     "enableCORS": { "kind": "attribute", "displayName": "Enable CORS", 
"label": "advanced", "required": false, "type": "boolean", "javaType": 
"java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "Whether to enable CORS headers in the 
HTTP response. This option will override what may be configured on a parent 
level The default value is false." },
     "apiDocs": { "kind": "attribute", "displayName": "Api Docs", "label": 
"advanced", "required": false, "type": "boolean", "javaType": 
"java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": true, "description": "Whether to include or exclude this rest 
operation in API documentation. The default value is true." },
     "deprecated": { "kind": "attribute", "displayName": "Deprecated", "label": 
"advanced", "required": false, "type": "boolean", "javaType": 
"java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "Marks this rest operation as deprecated 
in OpenApi documentation." },
+    "routeId": { "kind": "attribute", "displayName": "Route Id", "required": 
false, "type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "description": "Sets the id of the route" 
},
     "id": { "kind": "attribute", "displayName": "Id", "required": false, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "description": "Sets the id of this node" 
},
     "description": { "kind": "element", "displayName": "Description", 
"required": false, "type": "object", "javaType": 
"org.apache.camel.model.DescriptionDefinition", "deprecated": false, 
"autowired": false, "secret": false, "description": "Sets the description of 
this node" }
   }
diff --git 
a/core/camel-core-model/src/generated/resources/org/apache/camel/model/rest/restConfiguration.json
 
b/core/camel-core-model/src/generated/resources/org/apache/camel/model/rest/restConfiguration.json
index 582ff5e1c48..033245da87f 100644
--- 
a/core/camel-core-model/src/generated/resources/org/apache/camel/model/rest/restConfiguration.json
+++ 
b/core/camel-core-model/src/generated/resources/org/apache/camel/model/rest/restConfiguration.json
@@ -29,6 +29,7 @@
     "skipBindingOnErrorCode": { "kind": "attribute", "displayName": "Skip 
Binding On Error Code", "label": "advanced", "required": false, "type": 
"boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": false, "description": "Whether to skip 
binding on output if there is a custom HTTP error code header. This allows to 
build custom error messages that do not bind to json \/ xml etc, as success 
messages otherwise will do." },
     "clientRequestValidation": { "kind": "attribute", "displayName": "Client 
Request Validation", "label": "consumer,advanced", "required": false, "type": 
"boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": false, "description": "Whether to 
enable validation of the client request to check: 1) Content-Type header 
matches what the Rest DSL consumes; returns HTTP Status 415 if validation 
error. 2) Accept header matches what t [...]
     "enableCORS": { "kind": "attribute", "displayName": "Enable CORS", 
"label": "consumer,advanced", "required": false, "type": "boolean", "javaType": 
"java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "Whether to enable CORS headers in the 
HTTP response. The default value is false." },
+    "inlineRoutes": { "kind": "attribute", "displayName": "Inline Routes", 
"label": "consumer", "required": false, "type": "boolean", "javaType": 
"java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "Inline routes in rest-dsl which are 
linked using direct endpoints. By default, each service in Rest DSL is an 
individual route, meaning that you would have at least two routes per service 
(rest-dsl, and the route linked from res [...]
     "jsonDataFormat": { "kind": "attribute", "displayName": "Json Data 
Format", "label": "advanced", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "Name of specific json data format to use. By default jackson 
will be used. Important: This option is only for setting a custom name of the 
data format, not to refer to an existing data format instance." },
     "xmlDataFormat": { "kind": "attribute", "displayName": "Xml Data Format", 
"label": "advanced", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "Name of specific XML data format to use. By default jaxb will 
be used. Important: This option is only for setting a custom name of the data 
format, not to refer to an existing data format instance." },
     "componentProperty": { "kind": "element", "displayName": "Component 
Property", "label": "advanced", "required": false, "type": "array", "javaType": 
"java.util.List<org.apache.camel.model.rest.RestPropertyDefinition>", 
"deprecated": false, "autowired": false, "secret": false, "description": 
"Allows to configure as many additional properties for the rest component in 
use." },
diff --git 
a/core/camel-core-model/src/main/java/org/apache/camel/model/rest/RestConfigurationDefinition.java
 
b/core/camel-core-model/src/main/java/org/apache/camel/model/rest/RestConfigurationDefinition.java
index bb946a0f164..94aa94f90f5 100644
--- 
a/core/camel-core-model/src/main/java/org/apache/camel/model/rest/RestConfigurationDefinition.java
+++ 
b/core/camel-core-model/src/main/java/org/apache/camel/model/rest/RestConfigurationDefinition.java
@@ -89,6 +89,9 @@ public class RestConfigurationDefinition {
     @Metadata(label = "consumer,advanced", javaType = "java.lang.Boolean", 
defaultValue = "false")
     private Boolean enableCORS;
     @XmlAttribute
+    @Metadata(label = "consumer", javaType = "java.lang.Boolean", defaultValue 
= "false")
+    private Boolean inlineRoutes;
+    @XmlAttribute
     @Metadata(label = "advanced")
     private String jsonDataFormat;
     @XmlAttribute
@@ -330,6 +333,24 @@ public class RestConfigurationDefinition {
         this.enableCORS = enableCORS;
     }
 
+    public Boolean getInlineRoutes() {
+        return inlineRoutes;
+    }
+
+    /**
+     * Inline routes in rest-dsl which are linked using direct endpoints.
+     *
+     * By default, each service in Rest DSL is an individual route, meaning 
that you would
+     * have at least two routes per service (rest-dsl, and the route linked 
from rest-dsl).
+     * Enabling this allows Camel to optimize and inline this as a single 
route, however
+     * this requires to use direct endpoints, which must be unique per service.
+     *
+     * This option is default <tt>false</tt>.
+     */
+    public void setInlineRoutes(Boolean inlineRoutes) {
+        this.inlineRoutes = inlineRoutes;
+    }
+
     public String getJsonDataFormat() {
         return jsonDataFormat;
     }
@@ -611,6 +632,21 @@ public class RestConfigurationDefinition {
         return this;
     }
 
+    /**
+     * Inline routes in rest-dsl which are linked using direct endpoints.
+     *
+     * By default, each service in Rest DSL is an individual route, meaning 
that you would
+     * have at least two routes per service (rest-dsl, and the route linked 
from rest-dsl).
+     * Enabling this allows Camel to optimize and inline this as a single 
route, however
+     * this requires to use direct endpoints, which must be unique per service.
+     *
+     * This option is default <tt>false</tt>.
+     */
+    public RestConfigurationDefinition inlineRoutes(boolean inlineRoutes) {
+        setInlineRoutes(inlineRoutes);
+        return this;
+    }
+
     /**
      * To use a specific json data format
      * <p/>
@@ -791,6 +827,9 @@ public class RestConfigurationDefinition {
         if (enableCORS != null) {
             target.setEnableCORS(enableCORS);
         }
+        if (inlineRoutes != null) {
+            target.setInlineRoutes(inlineRoutes);
+        }
         if (jsonDataFormat != null) {
             target.setJsonDataFormat(jsonDataFormat);
         }
diff --git 
a/core/camel-core-model/src/main/java/org/apache/camel/model/rest/RestDefinition.java
 
b/core/camel-core-model/src/main/java/org/apache/camel/model/rest/RestDefinition.java
index facf13f6c53..2894f375357 100644
--- 
a/core/camel-core-model/src/main/java/org/apache/camel/model/rest/RestDefinition.java
+++ 
b/core/camel-core-model/src/main/java/org/apache/camel/model/rest/RestDefinition.java
@@ -333,10 +333,20 @@ public class RestDefinition extends 
OptionalIdentifiedDefinition<RestDefinition>
         return this;
     }
 
+    public RestDefinition routeId(String routeId) {
+        if (getVerbs().isEmpty()) {
+            throw new IllegalArgumentException("Must add verb first, such as 
get/post/delete");
+        }
+        // add on last verb as that is how the Java DSL works
+        VerbDefinition verb = getVerbs().get(getVerbs().size() - 1);
+        verb.setRouteId(routeId);
+        return this;
+    }
+
     public RestDefinition deprecated() {
         if (!getVerbs().isEmpty()) {
             VerbDefinition verb = getVerbs().get(getVerbs().size() - 1);
-            verb.deprecated();
+            verb.setDeprecated("true");
         }
 
         return this;
@@ -680,6 +690,10 @@ public class RestDefinition extends 
OptionalIdentifiedDefinition<RestDefinition>
         List<RouteDefinition> answer = new ArrayList<>();
 
         RestConfiguration config = camelContext.getRestConfiguration();
+        if (config.isInlineRoutes()) {
+            // sanity check this rest definition do not have duplicates linked 
routes via direct endpoints
+            validateUniqueDirects();
+        }
 
         addRouteDefinition(camelContext, answer, config.getComponent(), 
config.getProducerComponent());
 
@@ -699,6 +713,21 @@ public class RestDefinition extends 
OptionalIdentifiedDefinition<RestDefinition>
         }
     }
 
+    protected void validateUniqueDirects() {
+        Set<String> directs = new HashSet<>();
+        for (VerbDefinition verb : verbs) {
+            ToDefinition to = verb.getTo();
+            if (to != null) {
+                String uri = to.getUri();
+                if (uri.startsWith("direct:")) {
+                    if (!directs.add(uri)) {
+                        throw new IllegalArgumentException("Duplicate to in 
rest-dsl: " + uri);
+                    }
+                }
+            }
+        }
+    }
+
     protected String asTypeName(Class<?> classType) {
         // Workaround for https://issues.apache.org/jira/browse/CAMEL-15199
         //
@@ -769,6 +798,9 @@ public class RestDefinition extends 
OptionalIdentifiedDefinition<RestDefinition>
             if (verb.getTo() == null) {
                 throw new IllegalArgumentException("Rest service: " + verb + " 
must have to endpoint configured.");
             }
+            if (verb.getRouteId() != null) {
+                route.routeId(verb.getRouteId());
+            }
             route.getOutputs().add(verb.getTo());
 
             // add the binding
diff --git 
a/core/camel-core-model/src/main/java/org/apache/camel/model/rest/VerbDefinition.java
 
b/core/camel-core-model/src/main/java/org/apache/camel/model/rest/VerbDefinition.java
index 9329ddb591e..667e447b5a3 100644
--- 
a/core/camel-core-model/src/main/java/org/apache/camel/model/rest/VerbDefinition.java
+++ 
b/core/camel-core-model/src/main/java/org/apache/camel/model/rest/VerbDefinition.java
@@ -81,6 +81,8 @@ public abstract class VerbDefinition extends 
OptionalIdentifiedDefinition<VerbDe
     @XmlAttribute
     @Metadata(label = "advanced", javaType = "java.lang.Boolean", defaultValue 
= "false")
     private String deprecated;
+    @XmlAttribute
+    private String routeId;
     @XmlElement(required = true)
     private ToDefinition to;
 
@@ -110,6 +112,18 @@ public abstract class VerbDefinition extends 
OptionalIdentifiedDefinition<VerbDe
         return this;
     }
 
+    public String getRouteId() {
+        return routeId;
+    }
+
+    /**
+     * Sets the id of the route
+     */
+    public void setRouteId(String routeId) {
+        this.routeId = routeId;
+    }
+
+
     public List<ParamDefinition> getParams() {
         return params;
     }
diff --git 
a/core/camel-core/src/test/java/org/apache/camel/component/rest/FromRestInlineRoutesTest.java
 
b/core/camel-core/src/test/java/org/apache/camel/component/rest/FromRestInlineRoutesTest.java
new file mode 100644
index 00000000000..f5eed728bb3
--- /dev/null
+++ 
b/core/camel-core/src/test/java/org/apache/camel/component/rest/FromRestInlineRoutesTest.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.rest;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.spi.Registry;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class FromRestInlineRoutesTest extends ContextTestSupport {
+
+    @Override
+    protected Registry createRegistry() throws Exception {
+        Registry jndi = super.createRegistry();
+        jndi.bind("dummy-rest", new DummyRestConsumerFactory());
+        return jndi;
+    }
+
+    protected int getExpectedNumberOfRoutes() {
+        return 2; // inlined routes so there are only 2
+    }
+
+    @Test
+    public void testInlined() throws Exception {
+        assertEquals(getExpectedNumberOfRoutes(), context.getRoutes().size());
+
+        assertEquals(2, context.getRestDefinitions().size());
+        assertEquals(2, context.getRouteDefinitions().size());
+
+        // the rest becomes routes and the input is a seda endpoint created by
+        // the DummyRestConsumerFactory
+        String out = template.requestBody("seda:get-say-hello", "Me", 
String.class);
+        assertEquals("Hello World", out);
+        String out2 = template.requestBody("seda:get-say-bye", "Me", 
String.class);
+        assertEquals("Bye World", out2);
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                restConfiguration().host("localhost").inlineRoutes(true);
+
+                rest("/say/hello").get().to("direct:hello");
+                rest("/say/bye").get().to("direct:bye");
+
+                from("direct:hello").transform().constant("Hello World");
+                from("direct:bye").transform().constant("Bye World");
+            }
+        };
+    }
+}
diff --git 
a/core/camel-core/src/test/java/org/apache/camel/component/rest/FromRestRouteIdTest.java
 
b/core/camel-core/src/test/java/org/apache/camel/component/rest/FromRestRouteIdTest.java
new file mode 100644
index 00000000000..dd36316200f
--- /dev/null
+++ 
b/core/camel-core/src/test/java/org/apache/camel/component/rest/FromRestRouteIdTest.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.rest;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.model.RouteDefinition;
+import org.apache.camel.model.rest.CollectionFormat;
+import org.apache.camel.model.rest.RestParamType;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+public class FromRestRouteIdTest extends FromRestGetTest {
+
+    @Test
+    public void testFromRestModel() throws Exception {
+        super.testFromRestModel();
+        // should have getSayByeRoute
+        RouteDefinition def = context.getRouteDefinition("getSayByeRoute");
+        assertNotNull(def);
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                restConfiguration().host("localhost");
+                rest("/say/hello").get().to("direct:hello");
+
+                
rest("/say/bye").get().consumes("application/json").param().type(RestParamType.header)
+                        .description("header param 
description1").dataType("integer")
+                        .allowableValues("1", "2", "3", 
"4").defaultValue("1").name("header_count").required(true).endParam()
+                        .param().type(RestParamType.query)
+                        .description("header param 
description2").dataType("string").allowableValues("a", "b", "c", "d")
+                        
.defaultValue("b").collectionFormat(CollectionFormat.multi)
+                        
.name("header_letter").required(false).endParam().responseMessage().code(300).message("test
 msg")
+                        .responseModel(Integer.class).header("rate")
+                        .description("Rate 
limit").dataType("integer").endHeader().endResponseMessage().responseMessage()
+                        .code("error").message("does not 
work").endResponseMessage()
+                        .routeId("getSayByeRoute")
+                        .to("direct:bye").post().to("mock:update");
+
+                from("direct:hello").transform().constant("Hello World");
+
+                from("direct:bye").transform().constant("Bye World");
+            }
+        };
+    }
+}
diff --git 
a/core/camel-main/src/generated/java/org/apache/camel/main/RestConfigurationPropertiesConfigurer.java
 
b/core/camel-main/src/generated/java/org/apache/camel/main/RestConfigurationPropertiesConfigurer.java
index 25b9e827956..fbd8bc1b0bf 100644
--- 
a/core/camel-main/src/generated/java/org/apache/camel/main/RestConfigurationPropertiesConfigurer.java
+++ 
b/core/camel-main/src/generated/java/org/apache/camel/main/RestConfigurationPropertiesConfigurer.java
@@ -55,6 +55,8 @@ public class RestConfigurationPropertiesConfigurer extends 
org.apache.camel.supp
         case "Host": target.setHost(property(camelContext, 
java.lang.String.class, value)); return true;
         case "hostnameresolver":
         case "HostNameResolver": 
target.setHostNameResolver(property(camelContext, java.lang.String.class, 
value)); return true;
+        case "inlineroutes":
+        case "InlineRoutes": target.setInlineRoutes(property(camelContext, 
boolean.class, value)); return true;
         case "jsondataformat":
         case "JsonDataFormat": target.setJsonDataFormat(property(camelContext, 
java.lang.String.class, value)); return true;
         case "port":
@@ -112,6 +114,8 @@ public class RestConfigurationPropertiesConfigurer extends 
org.apache.camel.supp
         case "Host": return java.lang.String.class;
         case "hostnameresolver":
         case "HostNameResolver": return java.lang.String.class;
+        case "inlineroutes":
+        case "InlineRoutes": return boolean.class;
         case "jsondataformat":
         case "JsonDataFormat": return java.lang.String.class;
         case "port":
@@ -170,6 +174,8 @@ public class RestConfigurationPropertiesConfigurer extends 
org.apache.camel.supp
         case "Host": return target.getHost();
         case "hostnameresolver":
         case "HostNameResolver": return target.getHostNameResolver();
+        case "inlineroutes":
+        case "InlineRoutes": return target.isInlineRoutes();
         case "jsondataformat":
         case "JsonDataFormat": return target.getJsonDataFormat();
         case "port":
diff --git 
a/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json
 
b/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json
index efd1b33060a..da0c1336d03 100644
--- 
a/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json
+++ 
b/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json
@@ -191,6 +191,7 @@
     { "name": "camel.rest.endpointProperties", "description": "Sets additional 
options on endpoint level", "sourceType": 
"org.apache.camel.spi.RestConfiguration", "type": "object", "javaType": 
"java.util.Map" },
     { "name": "camel.rest.host", "description": "Sets the hostname to use by 
the REST consumer", "sourceType": "org.apache.camel.spi.RestConfiguration", 
"type": "string", "javaType": "java.lang.String" },
     { "name": "camel.rest.hostNameResolver", "description": "Sets the resolver 
to use for resolving hostname", "sourceType": 
"org.apache.camel.spi.RestConfiguration", "type": "object", "javaType": 
"org.apache.camel.spi.RestHostNameResolver", "defaultValue": 
"RestHostNameResolver.allLocalIp", "enum": [ "allLocalIp", "localIp", 
"localHostName" ] },
+    { "name": "camel.rest.inlineRoutes", "description": "Inline routes in 
rest-dsl which are linked using direct endpoints. By default, each service in 
Rest DSL is an individual route, meaning that you would have at least two 
routes per service (rest-dsl, and the route linked from rest-dsl). Enabling 
this allows Camel to optimize and inline this as a single route, however this 
requires to use direct endpoints, which must be unique per service. This option 
is default false.", "sourceType" [...]
     { "name": "camel.rest.jsonDataFormat", "description": "Sets a custom json 
data format to be used Important: This option is only for setting a custom name 
of the data format, not to refer to an existing data format instance.", 
"sourceType": "org.apache.camel.spi.RestConfiguration", "type": "string", 
"javaType": "java.lang.String" },
     { "name": "camel.rest.port", "description": "Sets the port to use by the 
REST consumer", "sourceType": "org.apache.camel.spi.RestConfiguration", "type": 
"integer", "javaType": "int" },
     { "name": "camel.rest.producerApiDoc", "description": "Sets the location 
of the api document (swagger api) the REST producer will use to validate the 
REST uri and query parameters are valid accordingly to the api document. This 
requires adding camel-swagger-java to the classpath, and any miss configuration 
will let Camel fail on startup and report the error(s). The location of the api 
document is loaded from classpath by default, but you can use file: or http: to 
refer to resources t [...]
diff --git a/core/camel-main/src/main/docs/main.adoc 
b/core/camel-main/src/main/docs/main.adoc
index 7bc34ab33c3..6d9f53c533a 100644
--- a/core/camel-main/src/main/docs/main.adoc
+++ b/core/camel-main/src/main/docs/main.adoc
@@ -175,7 +175,7 @@ The camel.health supports 7 options, which are listed below.
 |===
 
 === Camel Rest-DSL configurations
-The camel.rest supports 25 options, which are listed below.
+The camel.rest supports 26 options, which are listed below.
 
 [width="100%",cols="2,5,^1,2",options="header"]
 |===
@@ -197,6 +197,7 @@ The camel.rest supports 25 options, which are listed below.
 | *camel.rest.endpointProperties* | Sets additional options on endpoint level 
|  | Map
 | *camel.rest.host* | Sets the hostname to use by the REST consumer |  | String
 | *camel.rest.hostNameResolver* | Sets the resolver to use for resolving 
hostname | RestHostNameResolver.allLocalIp | RestHostNameResolver
+| *camel.rest.inlineRoutes* | Inline routes in rest-dsl which are linked using 
direct endpoints. By default, each service in Rest DSL is an individual route, 
meaning that you would have at least two routes per service (rest-dsl, and the 
route linked from rest-dsl). Enabling this allows Camel to optimize and inline 
this as a single route, however this requires to use direct endpoints, which 
must be unique per service. This option is default false. | false | boolean
 | *camel.rest.jsonDataFormat* | Sets a custom json data format to be used 
Important: This option is only for setting a custom name of the data format, 
not to refer to an existing data format instance. |  | String
 | *camel.rest.port* | Sets the port to use by the REST consumer |  | int
 | *camel.rest.producerApiDoc* | Sets the location of the api document (swagger 
api) the REST producer will use to validate the REST uri and query parameters 
are valid accordingly to the api document. This requires adding 
camel-swagger-java to the classpath, and any miss configuration will let Camel 
fail on startup and report the error(s). The location of the api document is 
loaded from classpath by default, but you can use file: or http: to refer to 
resources to load from file or http ur [...]
diff --git 
a/core/camel-main/src/main/java/org/apache/camel/main/RestConfigurationProperties.java
 
b/core/camel-main/src/main/java/org/apache/camel/main/RestConfigurationProperties.java
index 6b8af6b61c6..dca65a9e607 100644
--- 
a/core/camel-main/src/main/java/org/apache/camel/main/RestConfigurationProperties.java
+++ 
b/core/camel-main/src/main/java/org/apache/camel/main/RestConfigurationProperties.java
@@ -232,6 +232,21 @@ public class RestConfigurationProperties extends 
RestConfiguration implements Bo
         return this;
     }
 
+    /**
+     * Inline routes in rest-dsl which are linked using direct endpoints.
+     *
+     * By default, each service in Rest DSL is an individual route, meaning 
that you would
+     * have at least two routes per service (rest-dsl, and the route linked 
from rest-dsl).
+     * Enabling this allows Camel to optimize and inline this as a single 
route, however
+     * this requires to use direct endpoints, which must be unique per service.
+     *
+     * This option is default <tt>false</tt>.
+     */
+    public RestConfigurationProperties withInlineRoutes(boolean inlineRoutes) {
+        setInlineRoutes(inlineRoutes);
+        return this;
+    }
+
     /**
      * Name of specific json data format to use. By default jackson will be 
used. Important: This option is only for
      * setting a custom name of the data format, not to refer to an existing 
data format instance.
diff --git 
a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java 
b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java
index 8eb536fb300..d0db623bb8e 100644
--- 
a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java
+++ 
b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java
@@ -2903,6 +2903,7 @@ public class ModelParser extends BaseParser {
                 case "outType": def.setOutType(val); break;
                 case "path": def.setPath(val); break;
                 case "produces": def.setProduces(val); break;
+                case "routeId": def.setRouteId(val); break;
                 case "skipBindingOnErrorCode": 
def.setSkipBindingOnErrorCode(val); break;
                 case "type": def.setType(val); break;
                 default: return 
optionalIdentifiedDefinitionAttributeHandler().accept(def, key, val);
@@ -3070,6 +3071,7 @@ public class ModelParser extends BaseParser {
                 case "enableCORS": def.setEnableCORS(Boolean.valueOf(val)); 
break;
                 case "host": def.setHost(val); break;
                 case "hostNameResolver": 
def.setHostNameResolver(RestHostNameResolver.valueOf(val)); break;
+                case "inlineRoutes": 
def.setInlineRoutes(Boolean.valueOf(val)); break;
                 case "jsonDataFormat": def.setJsonDataFormat(val); break;
                 case "port": def.setPort(val); break;
                 case "producerApiDoc": def.setProducerApiDoc(val); break;
diff --git a/docs/user-manual/modules/ROOT/pages/rest-dsl.adoc 
b/docs/user-manual/modules/ROOT/pages/rest-dsl.adoc
index 0c49ea6afcf..14a55dd23aa 100644
--- a/docs/user-manual/modules/ROOT/pages/rest-dsl.adoc
+++ b/docs/user-manual/modules/ROOT/pages/rest-dsl.adoc
@@ -204,7 +204,59 @@ metrics about the routes, such as number of message 
processed, and their
 performance statistics.
 
 There is also a Rest Registry JMX MBean that contains a registry of all
-REST services which has been defined. 
+REST services which has been defined.
+
+== Inline Rest DSL as a single route
+
+Each of the rest services becomes a Camel route, and this means, that if the 
rest
+service is calling another Camel route via `direct`, which is a very common 
practice.
+This means that each rest service then becomes 2 routes. This can become 
harder to manage
+if you have many rest services.
+
+When you use `direct` endpoints then you can enable Rest DSL to automatically 
_inline_ the direct
+route in the rest route, meaning that there is only 1 route per rest service.
+
+To do this you *MUST* use `direct` endpoints, and each endpoint must be unique 
name per service.
+And the option `inlineRoutes` must be enabled.
+
+For example in the Java DSL below we have enabled inline routes and each rest 
service
+uses `direct` endpoints with unique names.
+
+[source,java]
+----
+restConfiguration().inlineRoutes(true);
+
+rest("/customers/")
+    .get("/{id}").to("direct:customerDetail")
+    .get("/{id}/orders").to("direct:customerOrders")
+    .post("/neworder").to("direct:customerNewOrder");
+----
+
+And in XML:
+
+[source,xml]
+----
+<restConfiguration inlineRoutes="true"/>
+
+<rest>
+  <get uri="/customers/{id}">
+    <to uri="direct:customerDetail"/>
+  </get>
+  <get uri="/customers/{id}/orders">
+    <to uri="direct:customerOrders"/>
+  </get>
+  <post uri="/customers/neworder">
+    <to uri="direct:customerNewOrder"/>
+  </post>
+</rest>
+----
+
+If you use Camel Main / Spring Boot / Quarkus / or Camel JBang you can also 
enable this in `application.properties` such as:
+
+[source,properties]
+----
+camel.rest.inline-routes = true
+----
 
 == Binding to POJOs using
 
@@ -431,13 +483,12 @@ The Rest DSL supports the following options:
 |===
 | Name | Description | Default | Type
 | *apiComponent* | Sets the name of the Camel component to use as the REST API 
(such as swagger or openapi) |  | String
-| *apiContextIdPattern* | Optional CamelContext id pattern to only allow Rest 
APIs from rest services within CamelContext's which name matches the pattern. 
The pattern #name# refers to the CamelContext name, to match on the current 
CamelContext only. For any other value, the pattern uses the rules from 
org.apache.camel.support.EndpointHelper#matchPattern(String,String) |  | String
 | *apiContextPath* | Sets a leading API context-path the REST API services 
will be using. This can be used when using components such as camel-servlet 
where the deployed web application is deployed using a context-path. |  | String
 | *apiHost* | To use a specific hostname for the API documentation (such as 
swagger or openapi) This can be used to override the generated host with this 
configured hostname |  | String
 | *apiProperties* | Sets additional options on api level |  | Map
 | *apiVendorExtension* | Whether vendor extension is enabled in the Rest APIs. 
If enabled then Camel will include additional information as vendor extension 
(eg keys starting with x-) such as route ids, class names etc. Not all 3rd 
party API gateways and tools supports vendor-extensions when importing your API 
docs. | false | boolean
 | *bindingMode* | Sets the binding mode to be used by the REST consumer | 
RestBindingMode.off | RestBindingMode
-| *clientRequestValidation* | Whether to enable validation of the client 
request to check whether the Content-Type and Accept headers from the client is 
supported by the Rest-DSL configuration of its consumes/produces settings. This 
can be turned on, to enable this check. In case of validation error, then HTTP 
Status codes 415 or 406 is returned. The default value is false. | false | 
boolean
+| *clientRequestValidation* | Whether to enable validation of the client 
request to check: 1) Content-Type header matches what the Rest DSL consumes; 
returns HTTP Status 415 if validation error. 2) Accept header matches what the 
Rest DSL produces; returns HTTP Status 406 if validation error. 3) Missing 
required data (query parameters, HTTP headers, body); returns HTTP Status 400 
if validation error. 4) Parsing error of the message body (JSon, XML or Auto 
binding mode must be enabled); re [...]
 | *component* | Sets the name of the Camel component to use as the REST 
consumer |  | String
 | *componentProperties* | Sets additional options on component level |  | Map
 | *consumerProperties* | Sets additional options on consumer level |  | Map
@@ -448,6 +499,7 @@ The Rest DSL supports the following options:
 | *endpointProperties* | Sets additional options on endpoint level |  | Map
 | *host* | Sets the hostname to use by the REST consumer |  | String
 | *hostNameResolver* | Sets the resolver to use for resolving hostname | 
RestHostNameResolver.allLocalIp | RestHostNameResolver
+| *inlineRoutes* | Inline routes in rest-dsl which are linked using direct 
endpoints. By default, each service in Rest DSL is an individual route, meaning 
that you would have at least two routes per service (rest-dsl, and the route 
linked from rest-dsl). Enabling this allows Camel to optimize and inline this 
as a single route, however this requires to use direct endpoints, which must be 
unique per service. This option is default false. | false | boolean
 | *jsonDataFormat* | Sets a custom json data format to be used Important: This 
option is only for setting a custom name of the data format, not to refer to an 
existing data format instance. |  | String
 | *port* | Sets the port to use by the REST consumer |  | int
 | *producerApiDoc* | Sets the location of the api document (swagger api) the 
REST producer will use to validate the REST uri and query parameters are valid 
accordingly to the api document. This requires adding camel-swagger-java to the 
classpath, and any miss configuration will let Camel fail on startup and report 
the error(s). The location of the api document is loaded from classpath by 
default, but you can use file: or http: to refer to resources to load from file 
or http url. |  | String

Reply via email to