Restlet — provides Restlet-based endpoints for consuming and producing RESTful resources
Restlet promotes decoupling of protocol and application concerns. The reference implementation of Restlet Engine supports a number of protocols. However, we have tested the HTTP protocol only.
The URI format for a Restlet endpoint is:
restlet:restletUrl[?options]
Format of restletUrl:
protocol://hostname[:port][/resourcePattern]
The default port is 80
. We do not automatically switch the default
port based on the protocol.
You can append query options to the URI in this format:
?option=value&option=value&...
Table 30, “Restlet endpoint options” lists the options for a Servlet endpoint.
Table 30. Restlet endpoint options
Name | Default | Description |
---|---|---|
headerFilterStrategy
| An instance of RestletHeaderFilterStrategy | Use the # notation
(headerFilterStrategy=# refName )
to reference a header filter strategy in the Camel Registry. The
strategy will be plugged into the restlet binding if it is
HeaderFilterStrategyAware . |
restletBinding
| An instance of DefaultRestletBinding | Use the # notation
(restletBinding=# refName )
to specify the bean ID of a RestletBinding object in the
Camel registry. |
restletMethod
|
GET
| On a producer endpoint, specifies the request method to use. On a
consumer endpoint, specifies that the endpoint consumes only
restletMethod requests. |
restletMethods
| None | Consumer only: Specifies one or more
methods separated by commas to be serviced by a restlet consumer
endpoint. restletMethods takes president over
restletMethod . |
restletRealm
|
null
| Use the # notation
(restletRealm=# refName )
to specify the bean ID of the Realm Map in the Camel registry. |
restletUriPatterns
| None | Consumer only: Specifies one ore
more URI templates to be serviced by a restlet consumer endpoint using
the # notation to reference a
List<String> in the registry. If a URI pattern has
been defined in the endpoint URI, both the URI pattern defined in the
endpoint and the restletUriPatterns option will be
honored. |
throwExceptionOnFailure
|
true
| Camel 2.6+Producer only: Throws an exception on a producer failure. |
![]() | Important |
---|---|
These component options cannot be configured on the endpoint. |
The Restlet component can be configured using the following options (available as Apache Camel 2.10 ) :
Name | Default | Description |
---|---|---|
controllerDaemon
|
true
| Indicates whether the controller thread should be a daemon (not blocking JVM exit). |
controllerSleepTimeMs
|
100
| Specifies the time, in milliseconds, for the controller thread to sleep between each control. |
inboundBufferSize
|
8192
| Specifies the size of the buffer when reading messages. |
minThreads
|
1
| Specifies the minimum number of threads that will wait to service requests. |
maxThreads
|
10
| Specifies the maximum number of threads that will service requests. |
maxConnectionsPerHost
|
-1
| Specifies the maximum number of concurrent connections per host (IP address). |
maxTotalConnections
|
-1
| Specifies the maximum number of concurrent connections in total. |
outboundBufferSize
|
8192
| Specifies the size of the buffer when writing messages. |
persistingConnections
|
true
| Indicates the whether connections should be kept alive after a call. |
pipeliningConnections
|
false
| Indicates the whether pipelining connections are supported. |
threadMaxIdleTimeMs
|
60000
| Specifies the time, in milliseconds, for an idle thread to wait for an operation before being collected. |
useForwardedForHeader
|
false
| Looks up the X-Forwarded-For header, supported
by popular proxies and caches, and uses it to populate the result of the
Request.getClientAddresses method. This
information is safe only for intermediary components within the local
network. Other addresses could easily be changed by setting a fake
header, so should not be trusted for serious security checks. |
reuseAddress | true | Enables/disables the SO_REUSEADDR socket option.
See the java.io.ServerSocket#reuseAddress property. |
Restlet endpoints use the following message headers:
Name | Type | Description |
---|---|---|
Content-Type
|
String
| Specifies the content type of the response message. If this header is
not set, the content type is based on the object type of the OUT message
body. If the content type is specified in the IN message, that value
determines the content type for the Restlet request message. Otherwise,
the content type is defaulted to
application/x-www-form-urlencoded . |
CamelAcceptContentType
|
String
| Specifies the HTTP Accept request header. |
CamelHttpMethod
|
String
| Apache Camel 2.9.3: Specifies the HTTP request method. This is set in the IN message header. |
CamelHttpQuery
|
String
| Specifies the query string of the request URI. It is set on the IN message the endpoint receives a request. |
CamelHttpResponseCode
| String or Integer | Specifies the response code to set on the OUT message by the application/processor. The value is the response code of the response message. If this header is not set, the response code is set by the restlet runtime engine. |
CamelHttpUri
|
String
| Specifies the HTTP request URI. This is set in the IN message header. |
CamelRestletLogin
|
String
| Specifies the login name for basic authentication. It is set on the IN message by the application and gets filtered before the restlet request header. |
CamelRestletPassword
|
String
| Specifies the password for basic authentication. It is set on the IN message by the application and gets filtered before the restlet request header. |
CamelRestletRequest
|
Request
| Apache Camel 2.8: Specifies the
org.restlet.Request object that holds all request
details. |
CamelRestletResponse
|
Response
| Apache Camel 2.8: Specifies the
org.restlet.Response object. You can use this
option to create responses using the Restlet API. |
org.restlet.*
| Specifies the attributes of a Restlet message that get propagated to Apache Camel IN headers. | |
cache-control | String or List<CacheDirective> | Apache Camel 2.11: User can set this option using either a
String value or a list of
CacheDirective . |
Apache Camel stores the restlet response from the external server in the OUT body. All headers from the IN message are copied to the OUT message, so that headers are preserved during routing.
The following route starts a restlet
consumer endpoint that listens
for POST
requests on
http://localhost:8080
. The processor creates a response that echoes the request body and the value of
the id
header.
from("restlet:http://localhost:9080/securedOrders?restletMethod=post&restletRealm=#realm").process(new Processor() { public void process(Exchange exchange) throws Exception { exchange.getOut().setBody( "received [" + exchange.getIn().getBody() + "] as an order id = " + exchange.getIn().getHeader("id")); } });
The restletRealm
setting in the URI query is used to look up a
Realm Map in the registry. If this option is specified, the restlet consumer uses the
information to authenticate user logins. Only authenticated
requests can access the resources. In this sample, we create a Spring application
context that serves as a registry. The bean ID of the Realm Map should match the
restletRealmRef.
<util:map id="realm"> <entry key="admin" value="foo" /> <entry key="bar" value="foo" /> </util:map>
The following sample starts a direct
endpoint that sends requests
to the server on
http://localhost:8080
(that is, our restlet consumer endpoint).
// Note: restletMethod and restletRealmRef are stripped // from the query before a request is sent as they are // only processed by Camel. from("direct:start-auth").to("restlet:http://localhost:9080/securedOrders?restletMethod=post");
That is all we need. We are ready to send a request and try out the restlet component:
final String id = "89531"; Map<String, Object> headers = new HashMap<String, Object>(); headers.put(RestletConstants.RESTLET_LOGIN, "admin"); headers.put(RestletConstants.RESTLET_PASSWORD, "foo"); headers.put("id", id); String response = (String) template.requestBodyAndHeaders("direct:start-auth", "<order foo='1'/>", headers);
The sample client sends a request to the direct:start-auth
endpoint
with the following headers:
CamelRestletLogin
(used internally by Apache Camel)
CamelRestletPassword
(used internally by Apache Camel)
id
(application header)
![]() | Important |
---|---|
|
The sample client gets a response like the following:
received [<order foo='1'/>] as an order id = 89531
It is possible to create a single route to service multiple HTTP methods using the
restletMethods
option. This snippet also shows how to retrieve
the request method from the header:
from("restlet:http://localhost:9080/users/{username}?restletMethods=post,get,put") .process(new Processor() { public void process(Exchange exchange) throws Exception { // echo the method exchange.getOut().setBody(exchange.getIn().getHeader(Exchange.HTTP_METHOD, String.class)); } });
In addition to servicing multiple methods, the next snippet shows how to create an
endpoint that supports multiple URI templates using the
restletUriPatterns
option. The request URI is available in the
header of the IN message as well. If a URI pattern has been defined in the endpoint URI
(which is not the case in this sample), both the URI pattern defined in the endpoint and
the restletUriPatterns
option will be honored.
from("restlet:http://localhost:9080?restletMethods=post,get&restletUriPatterns=#uriTemplates") .process(new Processor() { public void process(Exchange exchange) throws Exception { // echo the method String uri = exchange.getIn().getHeader(Exchange.HTTP_URI, String.class); String out = exchange.getIn().getHeader(Exchange.HTTP_METHOD, String.class); if ("http://localhost:9080/users/homer".equals(uri)) { exchange.getOut().setBody(out + " " + exchange.getIn().getHeader("username", String.class)); } else if ("http://localhost:9080/atom/collection/foo/component/bar".equals(uri)) { exchange.getOut().setBody(out + " " + exchange.getIn().getHeader("id", String.class) + " " + exchange.getIn().getHeader("cid", String.class)); } } });
The restletUriPatterns=#uriTemplates
option references the
List<String>
bean defined in the Spring XML configuration.
<util:list id="uriTemplates"> <value>/users/{username}</value> <value>/atom/collection/{id}/component/{cid}</value> </util:list>
Available as of Camel 2.8
You may want to use the org.restlet.Response
API to populate the
response. This gives you full access to the Restlet API and fine grained control of the
response. See the route snippet below where we generate the response from an inlined
Camel Processor:
from("restlet:http://localhost:" + portNum + "/users/{id}/like/{beer}") .process(new Processor() { public void process(Exchange exchange) throws Exception { // the Restlet request should be available if neeeded Request request = exchange.getIn().getHeader(RestletConstants.RESTLET_REQUEST, Request.class); assertNotNull("Restlet Request", request); // use Restlet API to create the response Response response = exchange.getIn().getHeader(RestletConstants.RESTLET_RESPONSE, Response.class); assertNotNull("Restlet Response", response); response.setStatus(Status.SUCCESS_OK); response.setEntity("<response>Beer is Good</response>", MediaType.TEXT_XML); exchange.getOut().setBody(response); } });
To configure the max threads options you must do this on the component, such as:
<bean id="restlet" class="org.apache.camel.component.RestletComponent"> <property name="maxThreads" value="100"/> </bean>
Available as of Camel 2.8 There are three ways to configure a Restlet application within a servlet container,
and using the subclassed, SpringServerServlet
, enables configuration
within Camel by injecting the Restlet Component.
Use of the Restlet servlet within a servlet container enables routes to be configured with relative paths in URIs (removing the restrictions of hard-coded absolute URIs) and the hosting servlet container to handle incoming requests (rather than have to spawn a separate server process on a new port).
To configure, add the following to your camel-context.xml;
<camelContext> <route id="RS_RestletDemo"> <from uri="restlet:/demo/{id}" /> <transform> <simple>Request type : ${header.CamelHttpMethod} and ID : ${header.id}</simple> </transform> </route> </camelContext> <bean id="RestletComponent" class="org.restlet.Component" /> <bean id="RestletComponentService" class="org.apache.camel.component.restlet.RestletComponent"> <constructor-arg index="0"> <ref bean="RestletComponent" /> </constructor-arg> </bean>
And add this to your web.xml;
<!-- Restlet Servlet --> <servlet> <servlet-name>RestletServlet</servlet-name> <servlet-class>org.restlet.ext.spring.SpringServerServlet</servlet-class> <init-param> <param-name>org.restlet.component</param-name> <param-value>RestletComponent</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>RestletServlet</servlet-name> <url-pattern>/rs/*</url-pattern> </servlet-mapping>
You will then be able to access the deployed route at http://localhost:8080/mywebapp/rs/demo/1234 where;
localhost:8080 is the server and port of your servlet container mywebapp is the name of your deployed webapp Your browser will then show the following content;
"Request type : GET and ID : 1234"
You will need to add dependency on the Spring extension to restlet which you can do in your Maven pom.xml file:
<dependency> <groupId>org.restlet.jee</groupId> <artifactId>org.restlet.ext.spring</artifactId> <version>${restlet-version}</version> </dependency>
And you would need to add dependency on the restlet maven repository as well:
<repository> <id>maven-restlet</id> <name>Public online Restlet repository</name> <url>http://maven.restlet.org</url> </repository>