AMF and PHP with Drupal and Flex

At my company we're working on a project where we're using Drupal as an administrative-facing data storage and content management system, and Flex as a client-facing user interface. We knew conceptually that this should be an easy task, since we knew we can create and expose an API to Drupal via the Services module. We were initially concerned, though, that we might have some difficulty getting Flex to work smoothly with these API. Turns out though, that our fears were unfounded -- with the help of the AMFPHP module, it couldn't have been easier. Below are instructions if you're interested in trying this out yourself. I'm tailoring this for experienced Drupal developers, so leave a comment if you have any questions.

The first step is to install the Services Module. This is just a simple matter of downloading the module and enabling it. It comes with some built-in services, so be sure to check them out. If you have some content on your site, you can try the services out right away via the module's admin interface, at /admin/build/services. Good ones to play around with (and look at the code if you're curious) are node.get and user.get. Now, these built-in services are cool, but if you're reading this you know that they're not most likely sufficient for your application's needs.

When you're ready to create your own services for making your website's API, it's good to refer to these pre-packaged services to see how they're done. If you haven't already done so, you will need to create a custom module for your site. The only required function in this module is a hook_service implementation, but you might also want to implement hook_perm to create your own service permissions. The service declarations go in your hook_service implementation, but you may also find it helpful to put the service definitions (callbacks) in a separate include file, just to keep things manageable if your listing gets large. It's important here to ensure your argument and return types are declared correctly, to ensure proper data conversion, but also to help your Flex developer out so he knows what he's working with!

As you're getting started, you may find it instructive to just copy over a pre-existing service definition and callback (such as node.get) into your own module, and rename functions appropriately. Then try testing out the function at the admin page and with any luck you should see it working. If so, go ahead and starting cloning at modifying it to meet your needs. You're well on your way to creating your site's API at this point!

The next step is to install and enable the AMFPHP Module. This module depends on the AMFPHP code package, so be sure to download that and place it in the AMFPHP module folder before you enable it.

That's almost all there is! If you're doing some non-standard practices you may have to tweak a few settings on the Services or AMFPHP admin settings page, but for the most part you can leave them as is. (Side note: you may want to use key authentication on a production site, but for testing purposes it's easier to work without using key authentication). We're getting really close to having Flex be able to easily exchange data with your site - there's just one thing left, and that's getting your site's AMFPHP gateway (the bridge between it and the outside world) to know how to describe your data.

Drupal rarely uses PHP classes in any of its core modules, but that's not sufficient here. If you're comfortable with Drupal code, you're probably also comfortable with using keyed (hash tables) and non-keyed arrays to move data around in Drupal. But we have to go object oriented here and create classes for our data. Since Flex makes heavy use of classes (and doesn't understand PHP's keyed arrays anyway), and we want to be able to pass data back and forth between Drupal and Flex, we have to agree on a data container that allows both applications be happy. We need both applications to be able to natively understand the data with no loss of structure or information. PHP classes are that data container, and we're going to make good use of them: our services are going to accept and return object instances of these classes.

So now it's time to create your classes. It doesn't matter where you put your class definitions but they should all be in one common folder. The reason is that you have to tell AMFPHP where these class definitions are located so it can correctly serialize and deserialize objects at its gateway (it's connection the world at large). You'll need to update a configuration file named globals.php in the root directory of the AMFPHP code you downloaded and placed in your AMFPHP module directory (this file is not to be confused with the configuration file Globals.php in amfphp/core/shared/app, though that one is important too, in it's own right). You need define the $voPath variable, which AMFPHP uses to store the location to your class definitions. Assuming your module is named "my_services," you'll need to add this:

$voPath = "sites/all/modules/my_services/vo";

And that's it! Now I'm not a Flex programmer so hopefully someone else will provide a tutorial for consuming the services on that end.

One thing that becomes tricky, now that your services are accepting objects as arguments, is testing. You can input strings, numbers, and arrays using the admin interface, but you can't input objects. I found that I had to insert lines of code to create dummy objects in my service callbacks. Once you have your Flex application up and running, the testing becomes a lot easier.

If you want to dig a little deeper into AMFPHP you can poke around in the amfphp/core folder in the module. The serializer/deserializer files in amfphp/core/amf/io are a good place to investigate low-level data conversion if you're curious or need to debug if things are going wrong.

Category:
Tags: , ,

Comments

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.

More information about formatting options

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.