Drupal coder: writing a Drupal XML-RPC service

Submitted by Frederic Marand on

XML-RPC is a very simple RPC service, but it may not be obvious how to provide it from Drupal. Here's how.

The API reference about XML-RPC within Drupal is fairly extensive, but with no clear README starting point, and may leave a very unwarranted an impression of complexity, although it is actually very simple to write XML-RPC services in Drupal, as chx explained on #drupal recently.

Here is the shortest XML-RPC server you can create in Drupal:

<?php
function rpc_xmlrpc()
  {
  return array (
'drupal.info'  => drupal_info ) ;
  }
?>

This one-liner is all you need for a minimal server! Now take the usual install steps:

  1. Save this as rpc.module
  2. Upload it to <drupal>/modules/rpc.module or <drupal>/modules/rpc/rpc.module
  3. Go to /admin/modules and enable the new, title-less, module
  4. You now have a working XML-RPC server ready to return an XML-RPC array with two elements. See function drupal_info() in drupal.module for the details.

You'll find more details in the API spec for hook_xmlrpc().

A word of warning

With all this simplicity comes a risk factor. Your RPC server will run just like any other module code, without builtin security checks like regular web pages, under whichever user account your module chooses (or anonymously if you don't choose one).

This means that you must at all costs include security checks in your new server module if you want it to access any data, otherwise you're ready to be exploited.

For the (rather common) EAI situation where RPC calls will be coming from just one IP address, limiting access to that address provides a good first level of protection without undue complexity. Here is an improved version of our small module, for Drupal 4.7:

<?php
/**
 * Provide a few help tips
 */
function rpc_help($section)
  {
  switch (
$section)
    {
    case
'admin/modules#name':
     
$ret = 'Foo XML-RPC module' ; break ;
    case
'admin/modules#description':
     
$ret = 'Module enabling integration with the Foo client' ; break ;
    case
'admin/help#rpc':
     
$ret 'Help for the Foo XML-RPC module' ; break ;
    }
  return
$ret ;
  }
 
/**
 * Define a drupal setting for the allowed IP address
 */
function rpc_settings()
  {
 
$form['rpc_allowed_ip'] = array
    (
   
'#type'          => 'textfield',
   
'#title'         => t('Allowed IP address in canonical format'),
   
'#default_value' => variable_get('rpc_allowed_ip', '127.0.0.1'),
   
'#size'          => 15,
   
'#maxlength'     => 15,
   
'#description' => t('RPC calls to this module from any other IP will be rejected. ')
      .
t('This does NOT affect other XML-RPC modules')
    );

  return
$form ;
  }

/**
 * Implementation of hook_xmlrpc
 */
function rpc_xmlrpc()
  {
 
$ret = array (
   
'drupal.info'    => drupal_info);

  if (
variable_get('rpc_allowed_ip', '') != $_SERVER['REMOTE_ADDR'])
    {
    foreach (
$ret as $methodname => $methodfun)
      {
$ret[$methodname] = _rpc_ip_ban; }
    }
 
  return
$ret ;
  }

/**
 * Return an error message.
 */
function _rpc_ip_ban()
  {
  return
t("This address is not allowed to access this RPC service");
  } 
?>

The nice trick is the use of the foreach loop on $ret, which remaps the method pointers to an error function from within just one hook, without having to install safety checks anywhere in the actual code performing the work with Drupal work. This could of course be much diversified, for a variety of access conditions.

Tagged for , , , .

Steve (not verified)

Tue, 2006-06-20 17:00

I'm breaking into developing for drupal/php. I understand what you're doing but in the context of the whole drupal api I agree about the information overload and no start page. Can you recommend a site or link with a more thorough tutorial for creating xml-rpc calls in drupal? Are there other ways to interface drupal with outside services other than xml-rpc or soap? Thanks

@IP : 70.91.81.142

Thanks for your comment. I found no such info on drupal.org myself, which is why I posted this tip here, when I was finally ready to admit it was that simple.

Actually, once you understand the first paragraph on the post, you're good to go, as long as you are developing XML-RPC server functionality within Drupal. Client functionality is built within PHP in most configurations anyway, and most XML-RPC related functions within Drupal are only there for Drupal core itself.

But it never hurts to type xmlrpc in the search form on api.drupal.org.

Yes indeed, OSInet provides paid support and development for Drupal, including by me.

For whomever is looking for custom module development or support around Drupal, please contact OSInet at sales [at] osinet.fr or use the french contact form, and we'll get in touch directly with you: I'd rather not mix this, my personal blog, with company business questions.

Jeremiah (not verified)

Tue, 2008-09-30 01:33

I've been doing some looking into xml-rpc and drupal, and I stumbled across this post.

It seems that everything I have found is geared towards using drupal as the database. Is it possible to use xml-rpc and drupal to pull live information out of another database? Or am I misunderstanding the point of xml-rpc?

If this is possible, are there any resources you could point me to?

Thanks!

Great tip, by the way.

Hi Jeremiah,

This post shows how to provide a service over XML-RPC to clients, which can themselves be written in just about anything. As you can see, it is not related to the database features, but of course can use it since the functions are in a module.

It is also possible to use XML-RPC within Drupal as a client but, again, this is in no way database-related: the client and server have to agree on predefined functions which will be made available remotely. Typically, these are at a higher abstraction level than database access, and have to implement access control, since Drupal does not use any form of in-database access control after the connection: all code can access all tables in the Drupal DB.

Note that it is (a little bit) less simple to write clients than servers.

Carlos (not verified)

Thu, 2009-09-10 11:58

Hi, I had just found your info about xml-rpc module, but I am afraid I am not sure how would I consume/invoke this server.

Does it have any URL I should get from or post to?
How do I invoke it?, which xml I need to post to it?

Regards

Once you installed this module on your server, it will be available to any XML-RPC client, at the endpoint (example): http://www.example.com/xmlrpc.php and using the method name drupal.info.

You can then invoke the method with the XML-RPC client library of your choice, or create your own: it's just a matter of serializing the data and POSTing them over HTTP.

You can find several examples of how to implement a PHP XML-RPC client to a Drupal XML-RPC service on the PHP-GTK community site at: http://php-gtk.eu/site/geo-nick, with 4 different client implementations of a client to the same XML-RPC service. These are built in PHP-GTK, but it doesn't change anything to the XML-RPC part, just the UI.

raul (not verified)

Sun, 2010-10-03 19:30

The info you gave is very rare. Thank You
But it was about XML-RPC server.

How can I implement Drupal XML-RPC client that sends request to a server?

Actually, my Drupal web-page displays some images. When clicked it will call a JSP application that will perform some operations on image. The application is already created.I only want to call this JSP app. from my Drupal's PHP code.
That's why I am asking how to put XML-RPC client in Drupal.
Any suggestions,highly appreciated.

Thank You

The syntax for clients is a bit different on D7 from what it used to be. Here is how to invoke system.methodHelp('system.listMethods') in all versions of Drupal from 4.7 to 7:

<?php
// Drupal 7 XML-RPC client example
// assuming devel.module is installed and server is on localhost
$x = xmlrpc('http://localhost/xmlrpc.php', array('system.methodHelp' => array('system.listMethods')));
dsm($x);
?>
<?php
// Drupal 4.7 to 6 XML-RPC client example
// assuming devel.module is installed and server is on localhost
$x = xmlrpc('http://localhost/xmlrpc.php', 'system.methodHelp', 'system.listMethods');
dsm($x);
?>

You might want to take a look at the xmlrpc_example submodule in the Examples module. We just finished polishing it for D7 these last few days.

Kerstboom (not verified)

Mon, 2010-11-29 19:49

Thanks for sharing. This is helpfull. I want to connect our Drupal kerstbomen webshop (Kerstbomen winkel) to our ERP system. Our ERP system supports XML-RPC as a server, so this is ideal to sync products and orders from and to Drupal.

Frederic Marand

Tue, 2010-11-30 08:46

In reply to by Kerstboom (not verified)

One thing to remember since you are connecting to a - likely sensitive - system like an ERP: you may want to add safety to your XML-RPC services. If the API provided by the ERP does not already include such features, you can protect the system at the network layer. Otherwise, if you can design the XML-RPC services at your choice, you may want to use encrypted content and single-use login tokens to avoid replay attacks.

bisht (not verified)

Wed, 2011-01-19 11:08

hi...

Thanks for this post.This coding will be helpful for many developers. who used Drupal.

Hi loheslath,

You will likely have better chance to obtain help by asking on the drupal support forums, on the #drupal or #drupal-consultants IRC channel, or on the Drupal consultants mailing list, all of which carry a much higher readership than a single blog.

This being said, you could write a drupal XML-RPC server which, as you can see from my article, is about as simple as it gets, to be on the server side of uploads, and use an XML-RPC client in your .NET app to access that server.