Implementing SOAP on cakePHP
3 : Complex Types
I have recently (last week) started using cakePHP. I choose cake because it works with AMFPHP and because I thought cake had built in support for web services (including soap). I'm not complaining, but I was somewhat disappointed to find out that support for web services is limited to routing, which I could not get to work anyway...
So we want to turn this result:
Enter VOs(value objects). Also known as structures(struc). A VO is nothing more than a simple object to hold the data. My vo for the Note class would look like this:
So, let's update our NotesController and view the results.
Now let's view the client results:
Now let's add the VO concept to the client code:
Client code:
Now client result is returned as a Note_vo object:
Array
(
[0] => 1
[1] => My first note
[2] => note body. bla, bla, bla, bla, bla, bla, bla.
[3] => 2006-10-29 07:23:42
[4] => 2006-10-29 07:23:42
)
into something with field names like this:
Array
(
[id] => 1
[title] => My first note
[body] => note body. bla, bla, bla, bla, bla, bla, bla.
[created] => 2006-10-29 07:23:42
[modified] => 2006-10-29 07:23:42
)
Enter VOs(value objects). Also known as structures(struc). A VO is nothing more than a simple object to hold the data. My vo for the Note class would look like this:
<?php
class Note_vo extends DataClass
{
/** @var int **/
public $id = 0;
/** @var string **/
public $title = '';
/** @var string **/
public $body = '';
/** @var string **/
public $created = '';
/** @var string **/
public $modified = '';
}
?>
Notice that each variable has a documented type. This is necessary for the automatic wsdl generation. Don't worry, you don't have to manually create a vo for each of your models; I have extended the bake script to create VOs.So, let's update our NotesController and view the results.
<?php
/**
* Get one record
* @param int
* @return Note_vo
*/
function view($id) {
$note = $this->Note->read(null, $id);
$this->set('note', $note);
$note_vo = new Note_vo($note['Note']);
return $note_vo;
}
?>
All I did was add one line
$note_vo = new Note_vo($note['Note']);
and then update the return type: @return Note_voNow let's view the client results:
<?php
stdClass Object
(
[body] => note body. bla, bla, bla, bla, bla, bla, bla.
[created] => 2006-10-29 07:23:42
[id] => 1
[modified] => 2006-10-29 07:23:42
[title] => My first note
)
?>
This is a pretty simple example so I should explain that your VO can contain other complex types (VOs), so you can exactly duplicate the structure of your model.Now let's add the VO concept to the client code:
Client code:
<?php
require('GenericDOM.php');
require('DataClass.php');
include('note.php');
$client = new SoapClient("http://ftc/soap5/wsdl/NotesController/", array('classmap' => array('Note_vo' => "Note_vo")) );
echo "<pre>";
echo "\n\n";
print_r( $client->view(1) );
echo "</pre>";
?>
Now client result is returned as a Note_vo object:
Note_vo Object
(
[id] => 1
[title] => My first note
[body] => note body. bla, bla, bla, bla, bla, bla, bla.
[created] => 2006-10-29 07:23:42
[modified] => 2006-10-29 07:23:42
)
Comments
Comment
1 Fantastic
One comment about securty: I've noticed that a lot of the public web services and api's have a login method which returns a "session id" which is then used on every other method. This helps as the login method can be done over SSL and the rest of them will be faster done over normal HTTP. In that way the username and password are not transferred in clear text over HTTP.
Comment
2 Nice
I've also implemented some SOAP services using CakePHP. But I have slightly different way to do it.
First of all I made the wsdl files manually (using Eclipse tools). It's quite important for me to have full control over my wsdl files.
Each SOAP service (port) has it's own controller, called soap_service_name_controller and there is route to each soap service and wsdl file defined in the `routes.php`.
It's simple way to link SOAP services defined in wsdl file with cake controllers.
When I find some spare time I will put an article describing my way of implementing SOAP services.
Question
3 Code and usage instructions
Comment
4 Example request
Can you post your way of doing SOAP service on top of cakePHP? Would be intrested to see that.