Question

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:

  1. It works.
  2. Easy to implement, maintain and manage.
  3. 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.
  4. 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:

  1. Client/Customer asks that you provide an app that queries the information stored on the database.
  2. 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?

Was it helpful?

Solution

To convert it, though this is off the top of my head, it would look something like this.

namespace MyApplication 
{ 
    public class myWebService : System.Web.Services.WebService 
    { 
        private classEmployee _emp = new classEmployee(); 

        [HttpGet]
        public string GetEmployees() 
        { 
            string EmployeeData = string.Empty; 
            EmployeeData = _emp.GetEmployees(); 
            return EmployeeData; 
        } 
    } 
}

And you could return that string in anything that is easily convertable by the consumer. If it's JavaScript then I would recommend JSON since it's native.

Let's talk about ReST for a minute. The part I find the most amusing about ReST is that the old fashioned ASMX services were ReSTful. But, since the IT industry has a problem with accepting the fact that an older technology may have been more correct all along they had to name it something fresh and new.

They did this with the term Client/Server as well. IBM was doing Client/Server operations years before Microsoft came around and said hey, we need to bring everything down to the PC. Well, when that started becoming less popular because deployment was a nightmare they realized, oh man, we need to go back to doing what IBM has been doing all along. Big servers, dumb clients, and simple deployments. But, they couldn't call it that because the industry wouldn't have accepted that and Microsoft didn't want that, so they called it The Cloud (insert bum, bum, bum music here).

So, fast-forward to SOAP. People wanted to be able to transfer complex objects over the wire and not have to deserialize them and they wanted flexibility of protocol. Well, SOAP gave you both, Microsoft generates the client representation and deserialization and the WCF layer allows real flexibility of protocol, whereas ReST can only be transmitted over HTTP because it uses the standard verbs.

So, the real answer to your question is, what do you need?

  1. SOAP is heavier and often less performant on very large data sets than ReST because it's not a native operation for the browser and the envelope is large. But then again, how much data should you really be transferring to the client?!?
  2. Do you want the one click generation of the client-side model? Then use SOAP.
  3. Do you want to make the API more accessable to other programming paradigms? Then use ReST.
  4. Do you want to go down the way of the rest of the industry at the moment? Then use ReST.

There is so much more discussion to be had but that should get you started. ReST is not better than SOAP, it's different, and it solves a different set of problems. Do not let yourself, or others talk you into, Law of the instrument.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top