ActiveApi - Wrapping a RESTful API in AS3
ActiveApi is my AS3 wrapper for a RESTful api, I just came up with ActiveApi right now so if I'm stepping on someones toes just let me know. In my last post I kind of went over how I came up with these classes so I'm just going to dive into some code.
To get started you need to define a controller class that extends from activeapi.base.Controller. This class should be a singleton, you can do that however you like. Controller defines a getter base\_url that just throws an error so you'll want to override that so it returns your base url. This is what you'll get:
{
import activeapi.base.Controller;
public class ExampleController extends Controller
{
public const BASE\_URL:String = "http://localhost:3001/";
private static var ExampleController = new ExampleController(true);
public function TrackerController(only\_one\_allowed:Boolean) {
}
public static function get inst(): ExampleController {
return \_instance;
}
public override function get base\_url():String {
return BASE\_URL;
}
}
}
Controller extends from EventDispatcher so you get all the event
listening and dispatching methods from that. This is the class that you
will add listeners to for CREATE and DELETE of your objects, like this:
Point to note, I'm prefixing the type of object I am creating to
the event string, this isn't the ideal design but it was the best I
could come up with.
Next is defining the class that is going to be doing the RESTful operations, the Session class in this example. For now I haven't found a reason to create a base class to extend from, instead you instantiate an object that will be used to delegate the work to. This is what the basic Session class would look like:
{
import mx.rpc.events.ResultEvent;
import activeapi.example.base.ActiveEvent;
import activeapi.example.base.ResourceHandler;
public class Session
{
//Static resource handler, passing in the name of the model and the controller instance.
private static var resource:ResourceHandler = new ResourceHandler("session", ExampleController.inst);
public var id:String;
public function Session(identifier:String)
{
id = identifier;
}
public static function create(args:Object):void {
//let the resource handler make the call
resource.create(args, create\_complete\_callback);
}
// static create method Session.create
private static function create\_complete\_callback(event:ResultEvent):void {
//delegate to the resource handler to handle the basic result and fire the events.
resource.handle\_and\_dispatch(ActiveEvent.CREATE, Session.parse(event.result), event);
}
public function destroy():void {
resource.destroy({id:id}, delete\_complete\_callback);
}
private function delete\_complete\_callback(event:ResultEvent):void {
resource.handle\_and\_dispatch(ActiveEvent.DELETE, null, event);
}
public static function parse(data:Object):Session {
//return a new session from the data
}
}
}
This class has a bit more going on. First off is the
ResourceHandler, it takes the name of the object type you want to create
and a Controller as it's parameters. I made mine static so that I could
use it in both my static create method and instance method destroy.
Under the covers the ResourceHandler sets up some HTTPService objects
pointing to the urls for creating and destroying the session object and
setting op the correct mehod and response type (XML). These objects
aren't accessible but are used by calling the create and destroy methods
on the ResourceHandler. In the callback I use another method on the,
handle\_and\_dispatch, to do some basic parsing of the response and then
dispatching the events on the controller. The second parameter of
handle\_and\_dispatch is an object and is added to the final event that
is dispatched. The auth method that was added to listen for session
CREATE before might look something like this:
if(Session(event.object).id!=null)
Application.application.currentState = "logged\_in"
else
Alert.show(event.message.toString());
}
And that's basically it. The ExampleController kind of acts like
a central messaging system and the major work is delegated to the
ResourceHandler. I still need to pull this out from the project I'm
using it for, which shouldn't take long, so if you're interested in the
code let me know in the comments. I'd also really appreciate some
feedback on the design choices and improvement suggestions. Personally
I'm still left feeling like there's a better way but trying to figure
something out has been sucking up way too much time.
Comments
comments powered by Disqus