Android client library for RESTful services
Table of Contents generated with DocToc
RESTrung was born out of the need to provide a clear and easy interface for Android apps @ 47 Degrees to interface with RESTful and HTTP based web services. Contributions and constructive feedback are welcome.
RESTrung may be automatically imported into your project if you already use Maven. Just declare RESTrung as a maven dependency. If you wish to always use the latest unstable snapshots, add the Sonatype repository where the RESTrung snapshot artifacts are being deployed. RESTrung official releases will be made available at Maven Central.
<repository>
<id>sonatype</id>
<url>https://oss.sonatype.org/content/groups/public/</url>
<releases>
<enabled>true</enabled>
<updatePolicy>daily</updatePolicy>
<checksumPolicy>fail</checksumPolicy>
</releases>
<snapshots>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
<checksumPolicy>ignore</checksumPolicy>
</snapshots>
</repository>
<dependency>
<groupId>it.restrung</groupId>
<artifactId>restrung</artifactId>
<version>1.0-SNAPSHOT</version>
<type>apklib</type>
</dependency>
You can get the releases, snapshots and other forms in which RESTrung is distributed from the Downloads page.
Whether you plan to use RESTrung for simple HTTP requests to a RESTful service or you need more control over requests, serialization, etc, we encourage you to read this short guide to fully understand what RESTrung is and what it is not.
The main interface to send requests and receive serialized responses is through RestClient whose default implementation you can access with the RestClientFactory. The RestClient exposes both Asynchronous and Synchronous operations for the most common HTTP verbs.
RestClientFactory.getClient().getAsync(new ContextAwareAPIDelegate<Target>(context, Target.class) {
@Override
public void onResults(Target response) {
//handle results here in the main thread
}
@Override
public void onError(Throwable e) {
//handle errors here in the main thread
}
}, "http://url/%s/%s", "param1", "param2");
Simple POST
//An object that implements JSONSerializable
AnyBeanObject sourceObject = new AnyBeanObject();
sourceObject.setName("name");
RestClientFactory.getClient().postAsync(new ContextAwareAPIDelegate<Target>(context, Target.class) {
@Override
public void onResults(Target response) {
//handle results here in the main thread
}
@Override
public void onError(Throwable e) {
//handle error here in the main thread
}
}, "http://url/%s/%s", sourceObject , "param1", "param2");
Multipart POST
File file = ....;
//An object that implements JSONSerializable
AnyBeanObject sourceObject = new AnyBeanObject();
sourceObject.setName("name");
RestClientFactory.getClient().postAsync(new ContextAwareAPIDelegate<Target>(context, Target.class) {
@Override
public void onResults(Target response) {
//handle results here in the main thread
}
@Override
public void onError(Throwable e) {
//handle error here in the main thread
}
}, "http://url/%s/%s", sourceObject, file , "param1", "param2");
//An object that implements JSONSerializable
AnyBeanObject sourceObject = new AnyBeanObject();
sourceObject.setName("name");
RestClientFactory.getClient().putAsync(new ContextAwareAPIDelegate<Target>(context, Target.class) {
@Override
public void onResults(Target response) {
//handle results here in the main thread
}
@Override
public void onError(Throwable e) {
//handle error here in the main thread
}
}, "http://url/%s/%s", sourceObject , "param1", "param2");
RestClientFactory.getClient().deleteAsync(new ContextAwareAPIDelegate<Target>(context, Target.class) {
@Override
public void onResults(Target response) {
//handle results here in the main thread
}
@Override
public void onError(Throwable e) {
//handle error here in the main thread
}
}, "http://url/%s/%s", "param1", "param2");
If you do not wish to use the RestClientFactory and RestClient interfaces you can get finer control by directly utilizing any of the loaders, asynctasks or runnable classes for each one of the operations.
- GET - it.restrung.rest.async.loaders.APIGetLoader
- POST - it.restrung.rest.async.loaders.APIPostLoader
- PUT - it.restrung.rest.async.loaders.APIPutLoader
- DELETE - it.restrung.rest.async.loaders.APIDeleteLoader
- GET - it.restrung.rest.async.asynctasks.APIGetAsyncTask
- POST - it.restrung.rest.async.asynctasks.APIPostAsyncTask
- PUT - it.restrung.rest.async.asynctasks.APIPutAsyncTask
- DELETE - it.restrung.rest.async.asynctasks.APIDeleteAsyncTask
- GET - it.restrung.rest.async.runnables.GetRunnable
- POST - it.restrung.rest.async.runnables.PostRunnable
- PUT - it.restrung.rest.async.runnables.PutRunnable
- DELETE - it.restrung.rest.async.runnables.DeleteRunnable
RESTrung includes a cache mechanism to help with fast retrieval of GET responses. RESTrung uses the request parameters and components to create a unique ID used as the cache key.
e.g.
Load always from cache
RestClientFactory.getClient().getAsync(
new ContextAwareAPIDelegate<Target>(context, Target.class, RequestCache.LoadPolicy.ENABLED) {
...
}, "http://url/%s/%s", "param1", "param2");
Load from cache if there is no internet connection
RestClientFactory.getClient().getAsync(
new ContextAwareAPIDelegate<Target>(context, Target.class, RequestCache.LoadPolicy.LOAD_IF_OFFLINE) {
...
}, "http://url/%s/%s", "param1", "param2");
The cache load policies available are:
- NEVER - Never use the cache.
- LOAD_IF_OFFLINE - Load from the cache when the app is offline.
- LOAD_ON_ERROR - Load from cache if there is an error.
- ETAG - Load from the cache if we have data stored and the server returns a 304 (not modified) response.
- ENABLED - Load always from the cache if available.
- LOAD_IF_TIMEOUT - Load from the cache when the request times out.
- NETWORK_ENABLED - Load from the cache then refresh the cache with a network call (calls onResult in the APIDelegate twice)
Access objects in the cache, invalidate, put and perform many other operations directly via the static methods available through the it.restrung.rest.cache.RequestCache class.
RESTrung comes with abstract classes that implement most of the tedious work related to serialize/deserialize javabeans to and from JSON. To have your beans auto-serialized when being sent as the body of both POST and PUT requests; make your class extend from it.restrung.rest.marshalling.request.AbstractJSONRequest or provide your own implementation of it.restrung.rest.marshalling.request.JSONSerializable
To have your beans auto-serialized when receiving a response body; make your class extend from it.restrung.rest.marshalling.response.AbstractJSONResponse or provide your own implementation of it.restrung.rest.marshalling.response.JSONResponse
You can customize the request before transmitting by overriding onRequest(RequestOperation) in your APIDelegate. If you wish to customize the response before being deserialized, simply override onResponse(ResponseOperation) in your APIDelegate.
e.g.
RestClientFactory.getClient().getAsync(new ContextAwareAPIDelegate<Target>(context, Target.class) {
...
public void onRequest(RequestOperation operation) {
//add request headers, setup basic auth, ...
}
public void onResponse(ResponseOperation operation) {
// intercept status code, ...
}
}, "http://url/%s/%s", "param1", "param2");