This post extends our discussion from Part 2. This series is comprised of Part 1, Part 2, and Part 3.
I will finish up this series by discussing three main topics as follows:
- What it exactly means to develop practical services that provide interfaces in terms of protocols and functionality.
- How the above supports mobile platform integration with enterprise systems.
- Provide a real world example demonstrating the consumption of enterprise system services by a mobile application.
In order for services developed in a Service-Oriented Architecture to be useful, they must be easy to communicate with and provide well-understood functionality. Although not a standard, the term RESTful embodies this and more. RESTful services are typically called using a normal HTTP GET and HTTP POST. And they return serialized data in a standard format, commonly JSON or XML. These standard formats are easily consumable by clients.
You might ask how this benefits mobile platforms. First, let’s look at what mobile platforms provide. They inherently possess three characteristics that make them ideal participants in an SOA as follows:
- Mobile platforms are obviously network enabled.
- They are computers possessing full processing power.
- They run on very capable, modern operating systems.
Given those points, mobile platforms have given rise to the latest smartphone frenzy, as they are really just another laptop, just much smaller and include phone capability. I also believe they will become the most ubiquitous computing devices on the planet within the next three years. If you have not used a smartphone, it is a great time to get one. Anyone working in the technology space must own a smartphone in order to understand where technology is taking us in the not-so-distant future. I tell folks all the time that you become enlightened by just using one everyday. And you discover new uses for it almost daily.
I will write a post with regards to this soon.
We have now covered topics 1 and 2 in our agenda. Now let’s discuss a real world example.
I’ll preface this with the fact that we will look at a simple example in ASP.NET MVC. Although not considered a hardcode service layer framework, such as a WCF-based service layer, this framework has developed nicely into one that can suit many situations, is code friendly, and easy to follow and describe. I am using what is considered a hybrid choice that blends ASP.NET MVC and WCF (you can read more about this here). This is perfect for our learning objectives!
Let’s state a simple use case. We want to retrieve a list of employees, ordered by last name. We’ll start by defining the service in an MVC controller called EmployeesController.
In ASP.NET MVC, the EmployeesController looks like this:
namespace SOAServices.Controllers
{
[WebApiEnabled]
public class EmployeesController : Controller
{
//
// GET: /Employees/
public ActionResult Index()
{
IEmployeeRepository repository = new EmployeeRepository();
return View(
repository.Retrieve()
.AsSerializable<Entities.DTOs.Employee>());
}
}
}
namespace SOAServices.Models.Abstract
{
public interface IEmployeeRepository
{
// define basic CRUD methods
IList<Entities.DTOs.Employee> Retrieve();
//Entities.DTOs.Employee Create();
//Entities.DTOs.Employee Update(Entities.DTOs.Employee emp);
//void Delete(int employeeId);
}
}
namespace SOAServices.Models.Concrete
{
public class EmployeeRepository : IEmployeeRepository
{
private EmployeeBusinessEntitiesDataContext _db = new EmployeeBusinessEntitiesDataContext(ConfigurationManager.ConnectionStrings["EmployeeDatabaseConnectionString"].ConnectionString);
public IList<Entities.DTOs.Employee> Retrieve()
{
var employees = _db.Employees
.OrderBy(emp => emp.LastName + emp.FirstName)
.Select(emp =>
new Entities.DTOs.Employee
{
FirstName = emp.FirstName,
LastName = emp.LastName,
Email = emp.Email,
Title = emp.Title,
Phone = emp.Phone,
Id = emp.Id,
DeptId = emp.DeptId,
SalaryGradeId = emp.SalaryGradeId,
TakesLongLunches = emp.TakesLongLunches
}
);
return employees.ToList();
}
}
}
namespace SOAServices.Entities.DTOs
{
[Serializable]
[DataContract]
public partial class Employee
{
[DataMember]
public string FirstName { get; set; }
[DataMember]
public string LastName { get; set; }
[DataMember]
public string Email { get; set; }
[DataMember]
public string Phone { get; set; }
[DataMember]
public string Title { get; set; }
[DataMember]
public int Id { get; set; }
[DataMember]
public int DeptId { get; set; }
[DataMember]
public int SalaryGradeId { get; set; }
[DataMember]
public bool TakesLongLunches { get; set; }
}
}
There is a lot going on with the small EmployeesController class, but I want to focus our attention on the Index() method. Let’s take a look at it again.
//
// GET: /Employees/
public ActionResult Index()
{
IEmployeeRepository repository = new EmployeeRepository();
return View(
repository.Retrieve()
.AsSerializable<Entities.DTOs.Employee>());
}
This small method is responsible for servicing an HTTP GET request by retrieving a list of ordered employees from the business repository class, serializing the results, and returning it as the response to the request.
Now let’s look at two real working examples demonstrating two popular serialization formats produced by this same service.
Additionally, notice how the same service call can even service an HTML page request.
Notice that each format contains the same data, just in a different format. This is really important for enabling Service-Oriented systems to support many different clients.
So how does all of this work so easily? We are using REST for ASP.NET MVC. As a hint, see the highlighted line below. This is taken from our EmployeesController class above.
[WebApiEnabled]
public class EmployeesController : Controller
{
This declaration enables web api functionality, such as the serialization of results to multiple formats.
And now we will look some Java code running on the Android mobile platform. We first look at a ResourceHelper class that contains the method retrieveAsString(…) designed to retrieve serialized resources from a service. We use this class to call the EmployeesController service we discussed above to retrieve the list of ordered employees. We’ll review a code snippet demonstrating actual usage in a bit.
public class ResourceHelper {
// Request the resource located at url and return
// it as a String.
public String retrieveAsString(String url) {
try {
URL resource = new URL(url);
InputStream inpStream = resource.openStream();
// Convert InputStream to String by using BufferedReader.readLine().
// Iterate until the BufferedReader returns null.  Each line will be
// appended to a StringBuilder, and the result returned as a String.
BufferedReader reader = new BufferedReader(new InputStreamReader(inpStream), 8192);
StringBuilder sb = new StringBuilder();
String line = null;
try {
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return sb.toString();
}
}
And this is our Employee class on the Android platform that represents an instance of an employee.
public class Employee {
public int Id;
public int DeptId;
public int SalaryGradeId;
public String FirstName;
public String LastName;
public String Email;
public String Phone;
public String Title;
public boolean TakesLongLunches;
public Employee(JSONObject obj) throws JSONException {
deserializeFromObj(obj);
}
public Employee(String serializedObj) throws JSONException {
deserialize(serializedObj);
}
public void deserialize(String serializedObj) throws JSONException {
JSONObject obj = new JSONObject(serializedObj);
deserializeFromObj(obj);
}
public void deserializeFromObj(JSONObject obj) throws JSONException {
this.Id = obj.getInt("Id");
this.DeptId = obj.getInt("DeptId");
this.SalaryGradeId = obj.getInt("SalaryGradeId");
this.FirstName = obj.getString("FirstName");
this.LastName = obj.getString("LastName");
this.Email = obj.getString("Email");
this.Phone = obj.getString("Phone");
this.Title = obj.getString("Title");
this.TakesLongLunches = Boolean.parseBoolean(obj.getString("TakesLongLunches"));
}
public String serialize() throws JSONException {
return serializeToObj().toString();
}
public JSONObject serializeToObj() throws JSONException {
JSONObject serializedObj = new JSONObject();
serializedObj.put("Id", this.Id);
serializedObj.put("DeptId", this.DeptId);
serializedObj.put("SalaryGradeId", this.SalaryGradeId);
serializedObj.put("FirstName", this.FirstName);
serializedObj.put("LastName", this.LastName);
serializedObj.put("Email", this.Email);
serializedObj.put("Phone", this.Phone);
serializedObj.put("Title", this.Title);
serializedObj.put("TakesLongLunches", this.TakesLongLunches);
return serializedObj;
}
public static ArrayList<Employee> deserializeArray(String serializedArray) throws JSONException {
JSONArray jsonObjs = new JSONArray(serializedArray);
ArrayList<Employee> employees = new ArrayList<Employee>();
for (int i=0; i<jsonObjs.length(); i++) {
JSONObject employee = jsonObjs.getJSONObject(i);
employees.add(new Employee(employee));
}
return employees;
}
}
And now we call our service, deserialize the results, and we have a list of employees that we can display in our Android application. In case you’re interested, in Android, lists are commonly displayed in a ListActivity. This is a discussion for another time. Here is the code to complete our final steps. It is quite small, so don’t blink.
try {
String serializedEmployees = new ResourceHelper().retrieveAsString(OUR_SERVICE_URL);
ArrayList<Employee> employees = Employee.deserializeArray(serializedEmployees);
}
catch (Exception e) {
e.printStackTrace();
}
Wow, how simple was that?! We can now communicate with our service in a standard and efficient way AND our service was developed in C# and our mobile client was developed in Java. From this discussion, you now have an understanding of how a Well-Defined SOA can Benefit Mobile Platform Integration with Enterprise Systems.
I sincerely hope this was helpful. See you soon!
public int Id = -1;
public int DeptId = -1;
public int SalaryGradeId = -1;
public String FirstName = “”;
public String LastName = “”;
public String Email = “”;
public String Phone = “”;
public String Title = “”;
public boolean TakesLongLunches = false;public boolean deserialize(String serializedObj) {
try {
JSONObject obj = new JSONObject(serializedObj);
this.Id = obj.getInt(“Id”);
this.DeptId = obj.getInt(“DeptId”);
this.SalaryGradeId = obj.getInt(“SalaryGradeId”);
this.FirstName = obj.getString(“FirstName”);
this.LastName = obj.getString(“LastName”);
this.Email = obj.getString(“Email”);
this.Phone = obj.getString(“Phone”);
this.Title = obj.getString(“Title”);
this.TakesLongLunches = Boolean.parseBoolean(obj.getString(“TakesLongLunches”));







