Rest Dispatch
Last updated
Was this helpful?
Last updated
Was this helpful?
REST Dispatch is a GWT client library introduced in GWTP 1.0. It allows your client code to send HTTP requests in a REST fashion to any server. It aims to support JSR-311 (or JAX-RS) annotations.
Only JSON serialization is supported!
##Reference Many example snippets are taken from the , a sample project used for integration tests within GWTP.
The serialization depends on the project. Whenever you create a pojo, you can use the to configure the serialization process!
##Setup Setting up your application to use REST Dispatch requires a few steps:
###1. Add REST Dispatch to your maven configuration To access the REST Dispatch classes, you need to add the following dependency to your pom file.
###Add REST Dispatch to your GWT module You need to add an inherits clause to your project's gwt.xml file
Very Important
If you use MvpWithFormFactor
or MvpWithEntryPoint
, the previous line needs to be before the MvpWith*
inherits tag. ie:
If you are using a generated GINjector and have something similar to
You need to change set-configuration-property
to extend-configuration-property
When you are using your own Ginjector -- that is if you are not using GWTP's generated ginjector -- you need to add gin.ginjector.modules
to GinModules
's properties attribute. This will ensure that generated GIN modules are installed.
###Install the REST Dispatch module To ensure the REST Dispatch can work properly, you need to install the RestDispatchAsyncModule
in your Gin module as well as bind RestApplicationPath
to your server API end-point.
The RestDispatchAsyncModuleBuilder
has the following configuration methods:
addGlobalHeaderParam
: See Global Parameters;
addGlobalQueryParam
: See Global Parameters;
interceptorRegistry
: Needs some documentation, see Client Action Handlers in the meanwhile;
exceptionHandler
: See Exception Handler;
requestTimeout
: The number of milliseconds to wait for a request to complete before throwing an exception. Defaults to 0 (no timeout);
serialization
: The serialization implementation to use. Defaults to JsonSerialization;
sessionAccessorType
: The class used to retrieve the value of your security cookie. Defaults to DefaultSecurityCookieAccessor;
xsrfTokenHeaderName
: See CSRF Protection.
####Resources You can create resources by following the steps below:
All resources must be interfaces;
You must annotate your resource with @Path
. All methods under this resource will be prepended with this path.
Methods must have one of the following return type:
If the return type is an interface (excluding collections and maps), the method will return a sub-resource;
If the return type is a RestAction<R>
, the method will return and end-point. You will be able to pass the returned instance to RestDispatch. The expected result is represented by the generic R
.
####Endpoints In RPC Dispatch, you needed to create custom implementations for every single action. In REST Dispatch, you return a parameterized interface and the implementation will be generated at compile-time.
Following the steps below, you can create and customize your endpoints:
All methods can be annotated by @Path("/anypath/{pathparam}")
. The string parameter will be appended to your resource's path. As demonstrated, you can optionally specify path parameters by enclosing them between {
curly braces}
. If a method is not annotated with @Path
, the resource's path will be used directly.
The HTTP Method is specified by annotating your method with the annotations provided by JSR 311. As of 1.4, REST Dispatch only supports @GET
, @PUT
, @POST
, @DELETE
and @HEAD
. One and only one of these annotation must be set on end-point methods.
For all the supported HTTP methods, you can use one or many of the following declarations:
The result is specified in the RestAction<R>
's generic. The following example will deserialize the response and give you a List<Car>
instance.
You can specify header parameters via the @HeaderParam
annotation. The following example will send the "Pragma" header along with any value you specify at runtime.
You can add query parameters to your request URI via the @QueryParam
annotation. The following example will create and send the request to a URI with the start and length parameters (ie.: /cars?start=3&length=25
).
You can specify path parameters to your request URI via the @PathParam
annotation. Your path must contain a parameter identical (case-sensitive) to the one given to @PathParam
. The following example will replace the {id}
parameter in your path by the specified id (/cars/5
).
Additionally, for @PUT
or @POST
, you can use either of these parameters, but not both:
You can add multiple parameters annotated with @FormParam
. The request body will then be formatted like a query string would be. The following example will generate this request body: username=admin&password=s3cr3t
.
Or you can provide a single object without any annotation and it will be serialized and sent as your request body. It must match the following rules to be a valid request body:
This parameter can be at any position in the signature;
There must be one and only one such parameter;
It must not be annotated by any of the previous annotations;
It must not be combined with any other @FormParam
parameters.
####Sub-resources If a resource returns another resource interface, then the returned resource will be a sub-resource. Methods returning a resource accept the same annotations and parameters then end-points. They will be carried all the way down to your endpoints.
###Use your REST resources {use-your-rest-resources} Using your resources is probably the most straight-forward step:
You need to inject RestDispatch
and your resource.
Then you will pass the instance returned by your delegate to RestDispatch, with a callback. ie:
Rest-Dispatch offers a built-in way to secure your server calls from CSRF attacks through a security cookie. To enable CSRF protection, you must bind @SecurityCookie
to the cookie name used to transport your security token.
The second configurable option is xsrfTokenHeaderName. It allows you to change the header used to transport your security token. The default value is X-CSRF-Token.
For example
will add this header for every getMe()
request sent to the server: Protection-Token: value_stored_in_jsessionid
.
You can also disable CSRF protection for specific endpoints or resources by using @NoXsrfHeader
. In the example above, all requests sent after calling details()
will not include the CSRF protection header. This annotation can be applied to resources, sub-resource methods and endpoint methods.
You can read CSRF Protection for more details.
If you have header or query parameters you wish to add to every requests, you can save up on the boilerplate by configuring them through RestDispatchAsyncModuleBuilder.addGlobalHeaderParam(String key)
and RestDispatchAsyncModuleBuilder.addGlobalQueryParam(String key)
.
The builder also makes it possible to specify to which HTTP methods the configured parameters should be attached.
For example
would configure the header Pragma: NoCache
for all DELETE, POST and PUT requests and the query parameter format=xml
for all GET requests.
Resource Delegates will allow your end-point methods to return the result type directly. This is very useful when you want to reuse your interfaces and the annotations on server implementations of those resources. The downside is that you will lose type safety from your callbacks.
There are some extension points available through the dispatch code. You should not need them unless you have a very specific use case. If you do, feel free to browse the code: many classes are extendable and have protected methods that you can override to extend their functionality. The generators also support extensions.
REST Dispatch tries to reduce the amount of boilerplate required by doing code generation. The customization is done through interfaces and annotations. Most annotations come from 's packages.
###Write resources See files under for resource examples.
Additionally, you can retrieve the raw object received from the server. To do so, pass a RestCallback
instead of an AsyncCallback
. You will have to implement an additional setResponse()
method. This method will be called before onSuccess
or onFailure
. Your endpoint call would then look like: