REST Based Webservices with MoltenCore

Introduction

Implementing Webservice clients can be a pain, there are many ways of doing it and even more ways to screw it up. MoltenCore provides you with many tools for implementing your Webservice Clients. Its goal is to help reduce the total number code required to access your data, thus freeing you up to focus on what really matters, doing something awesome with the data!

A slight diversion: Webservice Base Classes

MoltenCore provides you with the following base classes for Webservices

  • MVSRestWebserviceBase - Base class for webservices that follow the rest model.
  • MVSRPCServiceBase - Base Classe for all RPC Style Services
  • MVSJSONRPCServiceBase - Base Class for JSON RPC Services
  • MVSXMLRPCServiceBase - Base Class for XML RPC Services

The bulk of this article will be focused on introducing a new design pattern and the first base class listed above.

Delegates and the lack there of...

An interesting pattern you will see used through out all of the webservice classes is what I call the "Follow Me" pattern. The Follow Me pattern basically dictates that the ultimate object that is responding to a request of some kind, method invocation, webservice call, should be passed through to each step of the process. This design pattern is an antipattern of the delegate pattern. Though its an antipattern I feel that it is much better suited for webservices because of two important facts:

  1. Not having a single object responsible for handling webservice callbacks makes an app more robust.
  2. It allows you to have exactly one instance of your webservice ever (Singleton style) without fear that your Webservice delegate will be deallocated and cause a crash.

So let me provide you a simple example of a method that presumably implements the Follow Me pattern:

- (void)serviceCall1:(id<MVSWebserviceDelegate>)delegate callback:(SEL)selector;

Some basic notes:

  • The callback object (delegate) still has a required Objective-C protocol. This is done so we can ensure that the callback object implements some kind of an error handling method.
  • Secondly the method that gets called upon success is supplied at call time to the method.

The second note is perhaps the most important one. The user gets to specify the method they want called. Let that soak in for a second. I know that kinds of crazy. You get to decide how something is done. Yes there are a couple of rules but overall you are in control. Perhaps what I love about that this fact the most is when I am quickly whipping up a new project and I decide I want to try a couple of different ways of writing the code that handles the returned data I don't have to comment out code. I simply write two different methods and test them out side by side.

And no back to our regularly scheduled article...

Putting it all together

At this point you are probably thinking, "The Follow Me pattern is cool, but I thought we where discussing implementing webservice classes with MoltenCore". And you would be right, the Follow Me pattern is essential to understand though as I use it heavily in the webservice classes. So lets take a look at a basic class that contains the webservice call mentioned in the last section.

#import <Foundation/Foundation.h>
#import <MoltenCore/MoltenCore.h>

@interface ServiceClient : MVSRestWebserviceBase {
@private
}

- (id)init;

- (void)serviceCall1:(id<MVSWebserviceDelegate>)delegate callback:(SEL)selector;
@end

That is all straightforward I think. We define a class called ServiceClient that is of type MVSRestWebserviceBase. It has a single method called serviceCall1. The first thing we need to take a look at is the init method.

The designated initializer for MVSRestWebserviceBase is - initWithBaseURL:(NSString *)url; therefore our init method is:

- (id)init {
        if((self = [super initWithBaseURL:@"http://www.example.com/service"]) {
                // Other Implementation stuff
        }

        return self;
}

The base url you set will be used to derive the rest of your URLs for your calls.

Webservice calls in two lines

For the most part you can implement a webservice call (The part that actually makes the request) in two lines of code. Yup I have it done in two lines. Granted this overlooks a few things, like processing the data once it comes back, but that is handled in a separate method anyways.

That being said lets look at the implmentation of serviceCall1:

- (void)serviceCall1:(id<MVSWebserviceDelegate>)delegate callback:(SEL)callback {
        // Delegate - The object you want you calls to returned too or errors sent to
        // Callback - The Selector you want called when your data comes back.
        NSURLRequest *request = [self urlForRequest:@"serviceCall1.xml"];

        // Dispatch Request...
        // If self.isAsynchronise == YES then this will be stuffed in an operation queue, otherwise it will block.
        // callbackSelector - Selector within this client that you want called when the request has finished executing.
        [self dispatchRequest:request callbackSelector:@selector(myCallback1ForData:clientObject:callback:) delegate:delegate clientCallbackSelector:callback];
}