Sunday, February 3, 2013

Zero implementation PHP API Wrapper in C#

The MoneyMedic API wrapper NuGet package that I wrote in December doesn't actually implement the methods of the API. All the methods actually look something like this:

    internal class MoneyMedicAPI : IMoneyMedicApi
    {
        ...
        public get_invoices_response get_invoices(string api_key, 
                                                  MoneyMedicEnum.SortInvoicesBy sortby, 
                                                  MoneyMedicEnum.SortDir sortdir)
        {
            throw new NotImplementedException();
        }
    }

When figuring out how to implement the wrapper I obseved:

  • All API calls result in a URL call with a query string that holds the method parameters and values. Like https://www.moneymedic.eu/api/[METHOD_NAME/?[PARAMETER_NAME]=[PARAMETER_VALUE]&....etc....
  • The JSON or XML response will need to be parsed into an instance of some response class


Therefore I decided to use the following setup:

  • A method call on the IMoneyMedicAPI interface is being intercepted
  • The intercepted method name matches the actual method name, the parameter names match the actual parameter names ( although StyleCop doesn't like this too much ).
  • The interceptor creates the MoneyMedic URL from intercepted method name + creates the query string from the parameter names and their corresponding values.
  • Using JSON.NET, the result is parsed to a result object, that corresponds to the information in the documentation and returns this to the caller.


And thus the actual implementation is never used or called - hence the NotImplementedExceptions that will never be thrown

Here's the interceptor:
// -------------------------------------------------------------------------------
// 
//   2012 Jochen van Wylick
// 
// -------------------------------------------------------------------------------

namespace MoneyMedicAPI
{
    using Ninject.Extensions.Interception;

    /// 
    /// The money medic API interceptor.
    /// Intercepts calls to the MoneyMedicAPI.
    /// 
    public class MoneyMedicApiInterceptor : IInterceptor
    {
        #region IMethodInterceptor Members

        /// 
        /// The MoneyMedic interceptor.
        /// 
        /// 
        /// The invocation.
        /// 
        public void Intercept(IInvocation invocation)
        {
            // Get the parameter collection
            var parameters = invocation.Request.Method.GetParameters();

            // Get the argument collection
            var arguments = invocation.Request.Arguments;

            // Invoke the API call and return the value
            invocation.ReturnValue = MoneyMedicApiHelper.InvokeApiCall(
                invocation.Request.Method.Name, parameters, arguments, invocation.Request.Method.ReturnType);
        }

        #endregion
    }
}

This made the wrapper very easy to implement. Furthermore I could use it for other wrappers if I wanted but still provide IntelliSense to the caller.

No comments:

Post a Comment