Introduction
Consuming RESTful Web services that seemlessly support your data in a variety of representation media types and abtract away the low-level details of the client-server communication is not an easy task without a good toolkit. It is a powerful and exible toolkit that makes it easy to consume RESTful Services.
Representation State Transfer
REST stands for Representational State Transfer. (It is sometimes spelled "ReST".) It relies on a stateless, client-server, cacheable communications protocol and in virtually all cases, the HTTP protocol is used.
REST is an architecture style for designing networked applications. The idea is that, rather than using complex mechanisms such as CORBA, RPC or SOAP to connect between machines, simple HTTP is used to make calls between machines.
In many ways, the World Wide Web itself, based on HTTP, can be viewed as a REST-based architecture. RESTful applications use HTTP requests to post data (create and/or update), read data (e.g., make queries), and delete data. Thus, REST uses HTTP for all four CRUD (Create/Read/Update/Delete) operations.
Siminov Connect is a lightweight, comprehensive, open source REST framework for the Android platform. It reduces the workload involved in building and consuming RESTful APIs in Android. It supports major Internet transport, data format, and service description standards like HTTP and HTTPS, SMTP, XML, and JSON.
All the features you need
-
Easy Configuration
- Application Descriptor: Application Descriptor is the one which connects application to Siminov Framework. It provide basic information about application, which defines the behaviour of application.
<!-- Design Of ApplicationDescriptor.si.xml -->
<siminov>
<!-- General Application Description Properties -->
<!-- Mandatory Field -->
<property name="name">application_name</property>
<!-- Optional Field -->
<property name="description">application_description</property>
<!-- Mandatory Field (Default is 0.0) -->
<property name="version">application_version</property>
<!-- Database Descriptors Used By Application (zero-to-many) -->
<!-- Optional Fields -->
<database-descriptors>
<database-descriptor>full_path_of_database_descriptor_file</database-descriptor>
</database-descriptors>
<!-- Service Descriptors Used By Application (zero-to-many) -->
<service-descriptors>
<!-- Service Descriptor -->
<service-descriptor>full_path_of_service_descriptor</service-descriptor>
</service-descriptors>
<!-- Sync Descriptors Used By Application (zero-to-many) -->
<sync-descriptors>
<!-- Sync Descriptor -->
<sync-descriptor>full_path_of_sync_descriptor</sync-descriptor>
</sync-descriptors>
<!-- Notification Descriptor -->
<notification-descriptor>
<!-- Optional Field -->
<property name="name_of_property">value_of_property</property>
</notification-descriptor>
<!-- Library Descriptors Used By Application (zero-to-many) -->
<!-- Optional Fields -->
<library-descriptors>
<library-descriptor>full_path_of_library_descriptor_file</library-descriptor>
</librar-descriptors>
<!-- Event Handlers Implemented By Application (zero-to-many) -->
<!-- Optional Fields -->
<event-handlers>
<event-handler>full_class_path_of_event_handler_(ISiminovHandler/IDatabaseHandler)</event-handler>
</event-handlers>
</siminov>
- Service Descriptor: Service Descrptor is one which define the structure of your RESTful Web Service API:
<!-- Design Of ServiceDescriptor.si.xml -->
<service-descriptor>
<!-- General Service Properties -->
<!-- Mandatory Field -->
<property name="name">name_of_service</property>
<!-- Optional Field -->
<property name="description">description_of_service</property>
<!-- Optional Field (DEFAULT: HTTP) -->
<property name="protocol">HTTP|HTTPS</property>
<!-- Mandatory Field -->
<property name="instance">address_of_instance</property>
<!-- Optional Field -->
<property name="port">port_number</property>
<!-- Optional Field -->
<property name="context">context_of_service</property>
<!-- Requests -->
<!-- Request -->
<request>
<request>
<!-- General Request Properties -->
<!-- Mandatory Field -->
<property name="name">name_of_request</property>
<!-- Mandatory Field -->
<property name="type">GET|HEAD|POST|PUT|DELETE|TRACE|OPTIONS|CONNECT|PATCH</property>
<!-- Mandatory Field -->
<property name="api">full_request_path</property>
<!-- Mandatory Field -->
<property name="handler">handler_of_request</property>
<!-- Optional Field (DEFAULT: SYNC)-->
<property name="mode">SYNC|ASYNC</property>
<!-- Query Parameters -->
<!-- Query Parameter -->
<query-parameters>
<query-parameter>
<!-- Mandatory Field -->
<property name="name">name_of_query_parameter</property>
<!-- Mandatory Field -->
<property name="value">value_of_query_parameter</property>
</query-parameter>
</query-parameters>
<!-- Header Parameters -->
<!-- Header Parameter -->
<header-parameters>
<header-parameter>
<!-- Mandatory Field -->
<property name="name">name_of_header_parameter</property>
<!-- Mandatory Field -->
<property name="value">value_of_header_parameter</property>
</header-parameter>
</header-parameters>
<!-- Stream of Data Under Request Body -->
<!-- It is Optional Property -->
<data-stream>stream_of_data</data-stream>
</request>
</requests>
</service-descriptor>
- Sync Descriptor: Sync Descriptor is the one which define synchronization of data through service:
<!-- Design Of ServiceDescriptor.si.xml -->
<sync-descriptor>
<!-- Mandatory Field -->
<property name="name">name_of_sync_handler</property>
<!-- Optional Field -->
<property name="sync_interval">sync_interval_in_millisecond</property>
<!-- Optional Field -->
<!-- Default: SCREEN -->
<property name="type">INTERVAL|SCREEN|INTERVAL-SCREEN</property>
<!-- Service Descriptors -->
<!-- Service Descriptor -->
<service-descriptors>
<service-descriptor>name_of_service_descriptor.name_of_api</service-descriptor>
</service-descriptors>
</sync-descriptor>
- Library Descriptor: Library Descriptor is the which defines the properties of library:
<!-- Design Of LibraryDescriptor.si.xml -->
<library-descriptor>
<!-- General Properties Of Library -->
<!-- Mandatory Field -->
<property name="name">name_of_library</property>
<!-- Optional Field -->
<property name="description">description_of_library</property>
<!-- Database Mappings Needed Under This Library Descriptor -->
<!-- Optional Field -->
<!-- Database Mappings -->
<database-mapping-descriptors>
<database-mapping-descriptor>name_of_database_descriptor.full_path_of_database_mapping_descriptor_file</database-mapping-descriptor>
</database-mapping-descriptors>
<!-- Service Descriptors -->
<!-- Optional Field -->
<!-- Service Descriptor -->
<service-descriptors>
<service-descriptor>full_path_of_service-descriptor_file</service-descriptor>
</service-descriptors>
<!-- Sync Descriptors -->
<!-- Optional Field -->
<!-- Sync Descriptor -->
<sync-descriptors>
<sync-descriptor>full_path_of_sync_descriptor_file</sync-descriptor>
</sync-descriptors>
</library-descriptor>
-
Push Notification
Push notification is provide by all the platforms but in different forms and implementation. It provides a unique and generic implementation on all platforms with same APIs bundle and architecture.
-
Synchronization
Synchronizing your app data with service data is a tough job. It allows app to automatically checks for updates in the background. There are different ways by which you can synchronize your app data.
- Time Interval
- Screen Click
- Time Interval + Screen Click
-
Database Seeding
Since it is build top on Siminov Core, it provide all features related to database. You can easly map your Core Data Object with database. -
Events Notifier
It provides event notifier which gets triggered based on particular action. Using these you can easly take action based on event triggered.
- Sync Events:
ISyncEvents
are associated with sync operations.
public interface ISyncEvents {
public void onStart(ISyncRequest syncRequest);
public void onQueue(ISyncRequest syncRequest);
public void onFinish(ISyncRequest syncRequest);
public void onTerminate(ISyncRequest syncRequest);
}
- Notification Events:
INotificationEvents
contain events associated with notification.
public interface INotificationEvents {
public void onRegistration(IRegistration registration);
public void onUnregistration(IRegistration registration);
public void onNotification(IMessage message);
public void onError(NotificationException notificationException);
}
-
Service
Service is a client-side communication component that process and handles any web service request. It performs long running operations in the background. A Service is a group of Requests which deals on one particular web service.
An application usually consists of multiple services that are loosely bound to each other. Typically, a service in an application is specified to perform a given task for a specific web service. Each service can start another service in order to perform different action.
There are several callback methods that an service might receive, due to a change in its state-whether the framework is creating it, stopping it, resuming it, or destroying it-and each callback provides you the opportunity to perform specific work that’s appropriate to that state change. For instance, when stopped, your service should release any large objects, such as network or database connections.
When the service resumes, you can re-acquire the necessary resources and resume services that were interrupted. These state transitions are all part of the service lifecycle.
Let's discuss the basics of how to build and use a service, including a complete discussion of how the service lifecycle works, so you can properly manage the transition between various service states.
-
Creating a Service
To create a service, you must create a subclass of Service (or an existing subclass of it). In your subclass, you need to implement callback methods that the framework calls when the service transitions between various states of its lifecycle, such as when the service is being started, stopped, resumed, or destroyed.
The two most important callback methods are:
- onStart: This is the first method to be called when a service is created.
OnStart
is always overridden to perform any startup initializations that may be required by a Service such as:
- Initializing variables
- Binding static data to service
- Binding related screen to service
Once OnStart
has finished, Connect will call OnServiceQueue
if Service is in ASYNC mode else OnServiceRequestInvoke
.
- onRequestFinish(ConnectionResponse): This method is called after Web Service API is executed.
There are several other lifecycle callback methods that you should use in order to handle service transition change. All of the lifecycle callback methods are discussed later, in the section about Managing the Service Lifecycle.
-
Creating Service Descriptor
Using Service Descriptor you can describe the structure of your RESTful Web Service API. To declare your service descriptor, you have to create a service descriptor file in your application assets folder and add the same in your application descriptor too.
<service-descriptors>
<!-- Service Descriptor -->
<service-descriptor>full_path_of_service_descriptor</service-descriptor>
</service-descriptors>
-
Starting a Service
You can start your service by creating its instance, and calling invoke()
API. You can also pass additional resources to your service by using below Resource APIs:
-
addResource(key of your resource, your resource):
Using this API you can add additional resources to your service. -
containResource(key of your resource):
Using this API you can check whether resource exists with service or not.
Example:
LiquorBrand liquorBrand = new LiquorBrand();
liquorBrand.addResource(key_of_your_resource, your_resource);
liquorBrand.invoke();
-
Shutting down a service
You can shut down a service by calling its terminate() method.
Note
In most cases, you should not explicitly finish a service using these methods. As discussed in the following section about the service lifecycle, the framework manages the life of a service for you, so you do not need to terminate your own service. Calling these methods could adversely affect the expected user experience and should only be used when you absolutely do not want the user to return to this instance of the service.
-
Types of service execution
In service descriptor you can define the mode of service execution. Service execute in two ways:
<service-descriptor>
<requests>
<request>
<property name="mode">SYNC|ASYNC</property>
</request>
</requests>
</service-descriptor>
-
Foreground Service
A foreground service is a service that’s considered to be something the user is actively aware of and thus not a candidate for the system to kill when low on memory. A foreground service must provide a notification for the status bar, which is placed under the ”Ongoing” heading, which means that the notification cannot be dismissed unless the service is either stopped or removed from the foreground.
-
Background Service
A background service is one which runs without user interaction, it provide a straightforward structure for running an operation on a single background thread. This allows to handle long-running operations without affecting your user interface’s responsiveness. Also it is not affected by most user interface lifecycle events, so it continues to run in circumstances that would shut down an ASYNC Service.
To request that your service run in the background, you have to configure your service descriptor mode property to ASYNC.
-
Managing the Service lifecycle
Services are a fundamental building block of Connect Framework and they can exist in a number of different states. The service lifecycle begins with instantiation and ends with destruction, and includes many states in between. When a service changes state, the appropriate lifecycle event method is called, notifing the service of the implending state change and allowing it to execute code in order to adapt to that change.
Within the lifecycle callback methods, you can declare how your service behaves when their is any event on the service.
-
Overview
Services are an unusual programming concept specific to Siminov Connect. The service lifecycle is implemented as a collection of methods the application calls throughout the lifecycle of an service. These methods allow developers to implement the functionality that is necessary to satisfy the state and resource management requirements of their applications.
It is extremely important for the application developer to analyze the requirements of each service to determine which methods exposed by the service lifecycle need to be implemented. Failure to do this can result in application instability, inconsistant data.
-
Lifecycle
The Service lifecycle comprises a collection of methods exposed within the Service class that provide the developer with a resource management framework. This framework allows developers to meet the unique state management requirements of each service within an application and properly handle resource management.
Service States Service states can be broken into 4 main group as follows:
- Active or Running: Services are considered action or running if they are executing or processing.
- Paused: When the device goes to sleep, or there is no network communication, the service is considered paused. Paused services are still alive, that is, they maintain all state and member information, and remain attached to the application.
- Stopped: Service are considered stopped when they finish there process or are terminated.
- Resume:It is possible for a service that is anywhere from paused to stopped in the lifecycle to be removed from memory by application.
Lifecycle Methods As a developer, you can handle state changes by overriding these methods within a service. Its important to note, however, that all lifecycle methods may be called on the UI thread/Non UI thread and may block the OS from performing the next piece of UI work, such as hiding the current screen, displaying a new screen, etc. As such, code in these methods should be as brief as possible to make an application feel well performing. Any long-running tasks should be executed in ASYNC Service mode.
-
Request
- GET: It is used for retrieving data.
- HEAD: It is used to retrieve meta-information written in response headers, without having to transport the entire content.
- POST: It is used to request the server accept the entity enclosed in the request as a new subordinate of the web resource identified by the URI.
- PUT: It is used to request the enclosed entity be stored under the supplied URI.
- DELETE: Delete the specified resource.
- TRACE: Echoes back the received request so that a client can see what (if any) changes or additions have been made by intermediate servers.
- OPTIONS: Returns the HTTP methods that the server supports for the specified URL.
- CONNECT: Converts the request connection to a transparent TCP/IP tunnel, usually to facilitate SSL-encrypted communication (HTTPS) through an unencrypted HTTP proxy.
- PATCH: Is used to apply partial modifications to a resource.
-
Referring Resources
When you are creating Service Descriptor, there will be scenarios where you want to refer resources at a run time. By below ways you can refer resources from descriptor at run time.
-
Resource {@resource KEY OF RESOURCE}:
Passing resource as a parameter to request itself.
Example:
<request>
<property name="name">DELETE-LIQUOR</property>
<property name="type">DELETE</property>
<property name="api">delete-liquor</property>
<property name="handler">siminov.connect.sample.services.DeleteLiquor</property>
<property name="mode">ASYNC</property>
<header-parameters>
<header-parameter name="Accept">application/xml</header-parameter>
<header-parameter name="Content-Type">application/xml</header-parameter>
<header-parameter name="name">{@resource LIQUOR_NAME}</header-parameter>
</header-parameters>
</request>
Liquor liquor = new Liquor();
liquor.addResource('LIQUOR_NAME', name_of_liquor);
-
Reference {@refer REFERENCE_RESOURCE_FULL_PATH-PARAMETER_TO_REFERENCE_RESOURCE}
Call refered resource location to get value for property.
<request>
<property name="name">DELETE-LIQUOR</property>
<property name="type">DELETE</property>
<property name="api">delete-liquor</property>
<property name="handler">siminov.connect.sample.services.DeleteLiquor</property>
<property name="mode">ASYNC</property>
<header-parameters>
<header-parameter name="Accept">application/xml</header-parameter>
<header-parameter name="Content-Type">application/xml</header-parameter>
<header-parameter name="name">{@refer siminov.connect.sample.Refer.getLiquorName}</header-parameter>
</header-parameters>
</request>
-
Self Reference Resource {@self NAME_OF_PROPERTY_CONTAINED_WITHIN}
Get self reference resource from service descriptor itself.
<request>
<property name="name">DELETE-LIQUOR</property>
<property name="type">DELETE</property>
<property name="api">delete-liquor</property>
<property name="handler">siminov.connect.sample.services.DeleteLiquor</property>
<property name="mode">ASYNC</property>
<header-parameters>
<header-parameter name="Accept">application/xml</header-parameter>
<header-parameter name="Content-Type">application/xml</header-parameter>
<header-parameter name="name">{@self name}</header-parameter>
</header-parameters>
</request>
License
[SIMINOV FRAMEWORK]
Copyright [2015] [Siminov Software Solution|support@siminov.com]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http:
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Conclusion
If you are looking for a lightweight, easy and simple Restful Client Framework then Siminov Connect is the right place for you to get started. This not only handle your server communication but also allow you to synchronize your app data on periodic basis.
It also provides a generic way to handle the push notification, and database seeding for your application.