restendpoint
Asynchronous REST client based on Apache Http Async Client and Reactive Streams
Basically, restendpoint is convenient wrapper around Apache HttpComponents Async Client
Maven Dependencies
Last stable version:
<dependency>
<groupId>com.github.avarabyeu</groupId>
<artifactId>restendpoint-jdk6</artifactId>
<version>0.2.0</version>
</dependency>
Getting Started
As Simple As It’s Possible
Interface-based RestEndpoint
Using RestEndpoint, you do not need to create implementation of you http client. No any implementation at all! Only thing you need is to create interface with method declarations marked with appropriate annotations:
public interface SomeYourService {
/* just simple GET request */
@Request(method = HttpMethod.GET, url = "/")
String get();
/* GET request with placeholder in path */
@Request(method = HttpMethod.GET, url = "/{path}")
String getWithPath(@Path("path") String path);
/* GET request with query parameters, e.g. ?someParameter=someValue */
@Request(method = HttpMethod.GET, url = "/")
String getWithQuery(@Query Map<String, String> queryParams);
/* POST request with some body */
@Request(method = HttpMethod.POST, url = "/")
String post(@Body String body);
/* PUT request with some body */
@Request(method = HttpMethod.PUT, url = "/")
String put(@Body String body);
/* DELETE request */
@Request(method = HttpMethod.DELETE, url = "/")
String delete();
/* Asynchronous GET request */
@Request(method = HttpMethod.GET, url = "/")
Maybe<String> getAsync();
/* Asynchronous POST request */
@Request(method = HttpMethod.POST, url = "/")
Maybe<String> postAsync(@Body String body);
/* Asynchronous PUT request */
@Request(method = HttpMethod.PUT, url = "/")
Maybe<String> putAsync(@Body String body);
/* Asynchronous DELETE request */
@Request(method = HttpMethod.DELETE, url = "/")
Maybe<String> deleteAsync();
}
… and create instance of your service:
SomeYourService service = RestEndpoints.create()
.withBaseUrl("http://localhost")
.withSerializer(new StringSerializer())
.forInterface(RestInterface.class);
That’s it! RestEndpoint reads your interface and builds implementation based on Java Proxies. No any actions is required from you, http client is done.
Classic RestEndpoint
/* Creates default RestEndpoint */
RestEndpoint endpoint = RestEndpoints.createDefault("http://airports.pidgets.com/");
/* Executes GET request to
* http://airports.pidgets.com/v1/airports?country=Belarus&format=json
* asynchronously
*/
Maybe<String> airports = endpoint.get(
"/v1/airports",
ImmutableMap.<String, String>builder()
.put("country", "Belarus").put("format", "json").build(), String.class);
/* Waits for result and prints it once received */
System.out.println(airports.blockingGet());
Creating
Default and Simpliest
RestEndpoint endpoint = RestEndpoints.createDefault("http://airports.pidgets.com/");
Creates RestEndpoint with all available serializers, default http client configuration and built-in error handler.
Using Builder
RestEndpoint endpoint = RestEndpoints.create()
.withBaseUrl("http://base_url_of_rest_service")
.withSerializer(new GsonSerializer())
.withErrorHandler(new YourCustomErrorHandler())
.withBasicAuth("login", "password")
.build();
Creates RestEndpoint with only JSON serializer based on Google GSON, your custom error handler. Each request to server will contain Basic Authentication headers (preemptive authentication, see more details here: Apache Client Authentication)
Build HttpAsyncClient explicitly
Sometimes you need more deep http client configuration. Here is the example:
HttpAsyncClientBuilder httpClientBuilder = HttpAsyncClientBuilder.create();
CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials("user", "password"));
httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
httpClientBuilder.setMaxConnTotal(20);
httpClientBuilder.setMaxConnPerRoute(5);
RestEndpoint endpoint = RestEndpoints.create().withBaseUrl(HTTP_TEST_URK)
.withSerializer(new StringSerializer()).withHttpClient(httpClientBuilder.build())
.build();
So, you are able to configure HttpClient explicitly, but in this case builder’s methods like #withBasicAuth() will be overwritten.
Sending Requests
GET
Maybe<String> responseBody = endpoint.get("/", String.class);
POST/PUT
Maybe<String> postResponseBody = endpoint.post("/", "this is request body", String.class);
Maybe<String> putResponseBody = endpoint.put("/", "this is request body", String.class);
POST Multipart
MultiPartRequest multiPartRequest = new MultiPartRequest.Builder().
addBinaryPart("part name", "filename.txt",
MediaType.OCTET_STREAM.toString(),
ByteSource.wrap("here is body".getBytes())).
addSerializedPart("this part will be serialized using serializer", "part body").
build();
Maybe<String> post = endpoint.post("/", multiPartRequest, String.class);
Take a look at the request builder. We have possibility to provide some part as is (binary part, as byte array) and also we can add part which will be serialized using some serializer. This pretty convenient when you need to send multipart request with JSON’s, for example
DELETE
Maybe<String> deleteResponseBody = endpoint.delete("/", String.class);
AS COMMAND
RestCommand<String, String> command = new RestCommand<String, String>("/", HttpMethod.POST, "request body", String.class);
Maybe<String> to = endpoint.executeRequest(command);
Serializers
To provide a convenient way for working with different data formats, RestEndpoint uses serializers. Serializer is basically abstraction for converting data between java data types and data transmission formats (JSON, XML, String, etc). For example, if content type of your responses is ‘application/json’ you need to add GsonSerializer, based on Google Gson library (https://code.google.com/p/google-gson/)
RestEndpoint endpoint = RestEndpoints.create()
.withBaseUrl("http://base_url_of_rest_service")
.withSerializer(new GsonSerializer()).build();
RestEndpoint reads content type of incoming response and decides which serializer to use (based on response content type). It also adds correct content type to your outcoming requests depending on serializer used for body converting.
For now, RestEndpoints supports the following list of serializers:
- XML (based on JAXB - JaxbSerializer)
- JSON (based on Gson - GsonSerializer)
- Plain String (StringSerializer)
- Byte Array (ByteArraySerializer)
By the way, you can implement your own serializer (by implementing appropriate interface) and provide it to RestEndpoint.