A Quick Introduction to HTTP-RPC
Read on to see more on the HTTP-RPC open source framework for REST applications with examples in Java, Javascript, and Swift.
Join the DZone community and get the full member experience.
Join For FreeHTTP-RPC is an open-source framework for simplifying the development of REST-based applications. It allows developers to create and access HTTP-based web services using a convenient, RPC-like metaphor while preserving fundamental REST principles such as statelessness and uniform resource access.
The project currently includes support for implementing REST services in Java and consuming services in Java, Objective-C/Swift, or JavaScript. The server component provides a lightweight alternative to other, larger Java-based REST frameworks, and the consistent cross-platform client API makes it easy to interact with services regardless of the target device or operating system.
This article provides an introduction to the HTTP-RPC framework along with sample code demonstrating the implementation of a simple HTTP-RPC service in Java. Client examples in Swift, Java, and JavaScript are also provided.
Overview
HTTP-RPC services are accessed by applying an HTTP verb such as GET
or POST
to a target resource. The target is specified by a path representing the name of the resource and is generally expressed as a noun such as /calendar or /contacts.
Arguments are provided either via the query string or in the request body, like an HTML form. Results are generally returned as JSON, although operations that do not return a value are also supported.
For example, the following request might retrieve the sum of two numbers, whose values are specified by the a
and b
query arguments:
GET /math/sum?a=2&b=4
The service would return the value 6 in response.
Example Service
WebService
is an abstract base class for HTTP-RPC web services. Service operations are defined by adding public methods to a concrete service implementation.
The @RPC
annotation is used to flag a method as remotely accessible. This annotation associates an HTTP verb and a resource path with the method. All public annotated methods automatically become available for remote execution when the service is published.
For example, the following class might be used to implement the simple addition operation discussed in the previous section:
public class MathService extends WebService {
@RPC(method="GET", path="sum")
public double getSum(double a, double b) {
return a + b;
}
}
Java Client
Services operations are invoked in Java using an instance of the WebServiceProxy
class:
// Create service proxy
URL serverURL = new URL("https://localhost:8443");
ExecutorService executorService = Executors.newFixedThreadPool(10);
WebServiceProxy serviceProxy = new WebServiceProxy(serverURL, executorService);
// Get sum of "a" and "b"
serviceProxy.invoke("GET", "/math/sum", mapOf(entry("a", 2), entry("b", 4)), new ResultHandler() {
@Override public void execute(Number result, Exception exception) {
// result is 6
}
});
The result handler is a callback that will be executed upon completion of the request. In Java 7, anonymous inner classes are typically used to implement result handers. In Java 8 or later, lambda expressions can be used instead, reducing the invocation code to the following:
// Get sum of "a" and "b"
serviceProxy.invoke("GET", "/math/sum", mapOf(entry("a", 2), entry("b", 4)), (result, exception) -> {
// result is 6
});
Swift Client
The WSWebServiceProxy
class is used to invoke service operations in Swift. Result handlers are implemented using closures:
// Configure session
let configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
configuration.requestCachePolicy = NSURLRequestCachePolicy.ReloadIgnoringLocalAndRemoteCacheData
let delegateQueue = NSOperationQueue() delegateQueue.maxConcurrentOperationCount = 10
let session = NSURLSession(configuration: configuration, delegate: self, delegateQueue: delegateQueue)
// Initialize service proxy and invoke methods
let serverURL = NSURL(string: "https://localhost:8443")
let serviceProxy = WSWebServiceProxy(session: session, serverURL: serverURL!)
// Get sum of "a" and "b"
serviceProxy.invoke("GET", path: "/math/sum", arguments: ["a": 2, "b": 4]) {(result, error) in
// result is 6
}
JavaScript Client
In JavaScript, services are accessed using the WebServiceProxy
class. As in Swift, result handlers are implemented using closures:
// Create service proxy
var serviceProxy = new WebServiceProxy();
// Get sum of "a" and "b"
serviceProxy.invoke("GET", "/math/sum", {a:4, b:2}, function(result, error) {
// result is 6
});
Summary
This article introduced the HTTP-RPC framework and provided a brief example of how it can be used to create and consume cross-platform RESTful web services. For more information, please see the project README.
Published at DZone with permission of Greg Brown, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments