I've been longing to ask this question, but only found the time to do so now.
Anyways, there has been much of a discussion on Web Services (yeah, those traditional SOAP-XML response services) and RESTful services (which a lot of devs are into right now).
I feel that although I understand the concepts of REST in general, I need to learn more. I think one best way to totally embrace it is to show that it really is better (emphasis on ** as better is a subjective word) as what was being done currently.
Consider the following simple traditional codes: (This one is copied from an enterprise app with Oracle as backend. The database pretty much I think won't matter as you could readily switch between SQL Server or Oracle or any DB for that matter).
myWebService.asmx.cs
namespace MyApplication
{
public class myWebService : System.Web.Services.WebService
{
private classEmployee _emp = new classEmployee();
[WebMethod]
public string GetEmployees()
{
string EmployeeData = string.Empty;
EmployeeData = _emp.GetEmployees();
return EmployeeData;
}
}
}
classEmployee.cs
using System;
using System.Collections.Generic;
using System.Data;
using System.Globalization;
using System.Data.OracleClient;
namespace MyApplication.App_Code
{
public class classEmployee
{
private DataAccess _da;
public string GetEmployees()
{
string employeeData = string.Empty;
string cmd = string.Empty;
OracleCommand oraCmd = new OracleCommand();
DataSet ds = new DataSet();
try
{
cmd = "SELECT * FROM Employees";
oraCmd.CommandType = CommandType.Text;
oraCmd.CommandText = cmd;
ds = (DataSet)_da.ExecSQLQueryCmd(oraCmd, DataAccess.ResultType.DataSet);
employeeData = ds.GetXml
ds.Dispose();
}
catch (Exception ex)
{
employeeData = "Error: " + "Getting Employees [GetEmployees]" + Environment.NewLine + "Details: " + Environment.NewLine + ex.Message;
}
return employeeData;
}
}
}
DataAccess.cs
using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Data.OracleClient;
namespace MyApplication.App_Code
{
public class DataAccess
{
private OracleConnection oraConn;
private String connString;
public enum ResultType
{
DataReader = 0,
DataSet = 1,
DataTable = 2
}
public DataAccess()
{
connString = System.Configuration.ConfigurationManager.ConnectionStrings["AppConnectionString"].ConnectionString;
}
public object ExecuteSQLCommand(OracleCommand oraCommand, ResultType ReturnType, string TableName = "")
{
OracleDataAdapter oraDataAdapter = new OracleDataAdapter(oraCommand);
oraConn = new OracleConnection(sConnectionString);
try
{
oraConn.Open();
oraCmd.Connection = oraConn;
oraCmd.CommandType = CommandType.Text;
switch (ReturnType)
{
case ResultType.DataReader:
OracleDataReader oraDataReader = null;
oraDataReader = oraCmd.ExecuteReader();
return oraDataReader;
case ResultType.DataSet:
DataSet ds = new DataSet();
oDataAdapter.Fill(ds);
oraConn.Close();
oraConn.Dispose();
return ds;
case ResultType.DataTable:
DataTable dt = new DataTable();
if (!string.IsNullOrEmpty(TableName))
dt.TableName = TableName;
oDataAdapter.Fill(dt);
oraConn.Close();
oraConn.Dispose();
return dt;
}
}
catch (OracleException oException)
{
throw oException;
}
finally
{
oDataAdapter.Dispose();
oDataAdapter = null;
oraCmd.Dispose();
}
return null;
}
public int ExecuteSQLNonQueryCommand(OracleCommand oraCommand)
{
// This will execute any NON-QUERY command.
//Trimmed for Brevity purposes..
}
}
}
The above code is quite self explanatory. Invoke the web service and the get the resulting data in XML format. To execute non-query commands, simply replace the command string passed in the command object and call the necessary method in the DataAccess.cs class.
I am overwhelmed already with the different opinions on why the above should at least be avoided and instead go for RESTful service type calls. But I have not seen anything that at least helps convert this code to somewhat at least embrace the RESTful architecture.
I am pretty sure that a lot of people use this (mind you, I still use a lot of this currently) based on the reason that:
- It works.
- Easy to implement, maintain and manage.
- People doing database driven development are so much into SQL commands that being able to use those SQL chops that we use in the SQL editor easily into the application is a big sigh of relief. Why would you use an ORM when you can simply implement all your multiple queries (including Stored Procedures) using the above example.
- Most code examples available for data related apps show the same pattern as above (Dataset being populated from an Command object, and returned as DataSet or XML, etc..).
For one to accept what people terms as "Best Practice" in this area of coding, one should show why it is better, and how it is far easier to do such thing over the one that has been tried and tested to work.
If I may ask our fellow expert devs here to show me how to convert it, and some explanation on why the conversion to REST would be better (through the code), then I would be more than grateful for that.
Appreciate your inputs. Thanks.
Additional: I just want to point out that, although this is correct, I started to have some doubts whether this approach is the best after reading this article:
http://www.codeproject.com/Feature/WeirdAndWonderful.aspx?msg=4324770#xx4324770xx
The article above, as one commented on said - "Found this in a web service I'm upgrading. It's hard to find anything NOT wrong with this."
I am trying to establish as well what REALLY is wrong with this as I am in a bind.
Let me give you some situations:
- Client/Customer asks that you provide an app that queries the information stored on the database.
- You come up with the solution using the above method. Requirements asked by the customer is provided. The solution is reliable, fast and maintainable.
So in essence, the other question which I long to ask, is that, WHAT's really wrong with the code above?