26 June 2014

How to write a reliable web service

To increase the reliability of a web service you must need to implement following three basic points:
  1. Validate all input parameters.
  2. Result must be predictable to client. (Client can easily identify that call was successful or not)
  3. Handle all unhanded exceptions before sending result to client
Here I will give you a basic sample which has implemented above points.

namespace Test_WebServices
{
    
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    public class EmployeeService : System.Web.Services.WebService
    {

        [WebMethod]
        public GetEmployeeResult GetEmployee(string code)
        {
            GetEmployeeResult result = new GetEmployeeResult();

            try
            {
                //Always validate parameters and continue execution only if you got the desire value.
                if (ValidateParameter(code, result))
                {
                    
                    //Write you business logic
                    Employee emp = new Employee()
                    {
                        Code = code,
                        Name = "Employee A",
                        Phone = "123",
                        Address = "XYZ Street"
                    };

                    //Return the result with Success code.
                    result.ErrorCode = 0;
                    result.ErrorDesc = "Success";
                    result.Data = emp;
                }
            }
            catch (Exception ex)
            {
                //Instead of sending exception message to your potential client you can send generic exception in response
                //and send an error email to your self.

                result.ErrorCode = -100;
                result.ErrorDesc = "Message: " + ex.Message + " StackTrace:" + ex.StackTrace;
                result.Data = null;
            }

            return result;
        }

        private bool ValidateParameter(string code, GetEmployeeResult Result)
        {
            bool isValid;
            if (string.IsNullOrEmpty(code))
            {
                isValid = false;
                Result.ErrorCode = 1;
                Result.ErrorDesc = "Parameter 'code' is required";
            }
            else if (code.Length <= 2)
            {
                isValid = false;
                Result.ErrorCode = 2;
                Result.ErrorDesc = "Invalid 'code' found";
            }
            else
            {
                isValid = true;
            }
            return isValid;
        }


        public class GetEmployeeResult 
        {
            public int ErrorCode { get; set; }      //This will help caller to quickly identify problem
            public string ErrorDesc { get; set; }   //This can contain detail of the error if any
            public Employee Data { get; set; }      //This is hold the actual result of the service
        }


        public class Employee
        {
            public string Code { get; set; }
            public string Name { get; set; }
            public string Phone { get; set; }
            public string Address { get; set; }
        }
    }


}


Always encapsulate the result in a custom object and send that custom object to client. In our case we are sending 'GetEmployeeResult' object to client. Client of this service can easily identify that the call is successful or not by checking ErrorCode variable. Here is sample code of caller.

EmployeeServiceSoapClient client = new EmployeeServiceSoapClient();
GetEmployeeResult result = client.GetEmployee("E101");
if (result.ErrorCode != 0)
{
    throw new Exception("Error in service : ErrorCode=" + result.ErrorCode + " - ErrorDesc=" + result.ErrorDesc);
}

//Finally we got the data
Employee emp = result.Data;

You can implement these points in any service (WCF, PHP or Java based services) to increase reliability of your code.