-
Notifications
You must be signed in to change notification settings - Fork 16
Defining Endpoint Contracts 1.2.3
######The intended use of an endpoint contract is to identify a set of remote services and provide information for successful communication.
You start off by copying the endpoint contract of a web service, or defining new request methods, on a single interface. This interface is then annotated to provide information (metadata) on how to reach the endpoint services and communicate with them.
Almost all usage of the RoboZombie API revolves around this set of annotations for populating endpoint metadata.
####1. Identifying Endpoints
The @Endpoint
annotation is used to mark interfaces which specify contracts for remote endpoints.
- It takes a mandatory host parameter which specifies the target endpoint host-name for all request invocations.
@Endpoint("www.google.com")
public interface CurrencyConverterEndpoint {}
* It can be optionally configured to use a different scheme and port, along with a root-path.
@Endpoint(scheme = "https", value = "www.google.com", port = "443", path = "/ig/calculator")
public interface CurrencyConverterEndpoint {}
####2. Defining Request Methods
If the invocation target is a web service, the set of web methods on the service contract may be copied directly. If request methods are created anew, they should be self-explanatory and cover all the parameters of the conversation.
- Each request method can be identified using the
@Request
annotation.
@Request
public abstract String timestamp();
By default each invocation executes as an HTTP GET request on the endpoint root-path with no request parameters.
* To populate request parameters, define them as arguments to the method and annotate them with ```@Param```.
@Request
public abstract String convert(@Param("q") String conversionString);
- A request may also be configured to use an alternative HTTP method type or be invoked on a sub-path from the root.
@Request(path = "/ig/calculator", method = RequestMethod.HTTP_POST)
public abstract String convert(@Param("q") String conversionString);
- For request parameters which remain constant for a particular invocation context can be defined using
@Request.Param
annotations.
@Request(path = "/ig/calculator", params = {@Request.Param(name = "hl", value = "en")})
public abstract String convert(@Param("q") String conversionString);
For request parameters which are populated rarely, use an
@Param
annotation with adefaultValue
attribute to fallback to if null is received.
####3. Populating Headers
HTTP headers are treated differently depending on the frequency with which they change.
#####a) Request Headers
RoboZombie sorts these into two sets, those which remain constant throughout an endpoint lifetime and those which may change per invocation.
-
Static headers are defined at the method level using the
@HeaderSet
annotation which takes a set of@HeaderSet.Header
annotations.
@Request
@HeaderSet({@HeaderSet.Header(name = "Accept", value = "application/rss+xml"),
@HeaderSet.Header(name = "Accept-Charset", value = "utf-8")})
public abstract String getRSSFeed();
-
Dynamic headers are populated via method arguments annotated with
@Header
.
@Request
public abstract String crawlBlog((@Header("User-Agent") String userAgent)
#####b) Response Headers
Request headers which are modified or introduced at the remote end should be defined as type StringBuilder
. This allows the header to be treated as an in-out variable.
######Definition
@Request
public abstract String echo(@Param("s") String echoString,
@Header("Server") StringBuilder serverName);
######Invocation
StringBuilder serverName = new StringBuilder();
String response = endpoint.echo("HELLO", serverName);
logger.info(serverName.toString() + " says " + response);
######Output
$ Jetty(7.0.x) says HELLO
An alternative to this is to use a custom response parser and process the returned headers manually.