Archive

Posts Tagged ‘webservice’

How-To Create a RESt Webservice with Zend Rest

August 13th, 2010 Ivan Villareal No comments

There are many times when we need to get data from a production application, but the application is running on a different server, or has a different db than the one we are currently working.

So a quick way to get the required data, without modifying the app would be to create a webservice to expose the data needed.

There are several ways to do this, RPC, SOAP, RESt, to name a few, we can even use some non standard methods, but the discussion of this is beyond the scope of this post.

Thanks to the Zend Framework, we can easily write an api and have working REST server within minutes, even if you don’t use the Zend Framework in your application you can just grab the needed files, and you’ll have your server up and running.

This is the way I can quickly expose some data of a current system.

First get the Zend Framework from Latest Zend Framework.

If you don’t want to put all the framework in your library, you can just use the following files to create your REST server.

|-- Exception.php
|-- Rest
|   |-- Client
|   |   |-- Exception.php
|   |   |-- Result
|   |   |   `-- Exception.php
|   |   `-- Result.php
|   |-- Client.php
|   |-- Controller.php
|   |-- Exception.php
|   |-- Route.php
|   |-- Server
|   |   `-- Exception.php
|   `-- Server.php
`-- Server
    |-- Abstract.php
    |-- Cache.php
    |-- Definition.php
    |-- Exception.php
    |-- Interface.php
    |-- Method
    |   |-- Callback.php
    |   |-- Definition.php
    |   |-- Parameter.php
    |   `-- Prototype.php
    |-- Reflection
    |   |-- Class.php
    |   |-- Exception.php
    |   |-- Function
    |   |   `-- Abstract.php
    |   |-- Function.php
    |   |-- Method.php
    |   |-- Node.php
    |   |-- Parameter.php
    |   |-- Prototype.php
    |   `-- ReturnValue.php
    `-- Reflection.php
 
8 directories, 29 files

Once you have saved the above files somewhere (I use lib/Zend), start writing your server.

< ?php
set_include_path('./lib' . PATH_SEPARATOR . get_include_path());
 
/**
 * Include the main class that we will use
 * to get the data from.
 */
require_once 'DomainProcessor.php';
require_once 'Zend/Rest/Server.php';
 
 
 
class domainService
{
    private $_domainProcessor;
 
    public function __construct()
    {
         $this->_domainProcessor = new domainProcessor();
    }
 
    /**
     * This method will expose the data
     * so we make the call and return what we want to
     * publish
     */
    public function getDomainData($domain)
    {
        $domain = strtolower($domain);
        $result = $this->_domainProcessor->_getDomainData($domain);
        if ($result['fullDomainName'] != $domain) {
            $result = false;
        }
        return $result;
    }
}
 
/**
 * We instantiate a Zend_Rest_Server
 * and we pass the class name that we 
 * want to expose, Zend_Rest will take
 * care of everything else, all our public
 * methods can be consumed by a RESt client
 */
$server = new Zend_Rest_Server();
$server->setClass('domainService');
$server->handle();

To consume our webservice we call it either using a GET or a POST, we can use Zend_Rest_Client to write a client, but also we can call it manually just to be sure that everything works.

To call the above class would be something like:

http://blog.ivanvillareal.info/api.php?method=getDomainData&domain=ivanvillareal.com

and it should respond something like this:

01
<domainservice generator="zend" version="1.0">
02
 <getdomaindata>
03
 <response>
04
 <name>ivanvillareal.com</name>
05
 <age>1</age>
06
 <owner>me</owner>
07
 </response>
08
 <status>success</status>
09
 </getdomaindata>
10
</domainservice>

PHP cross domain ajax Proxy

March 19th, 2010 Ivan Villareal No comments

I received a javascript application, that made cross domain calls to a webservice using the flensed library, this was pretty neat, but filling the dropdown boxes was very slow. Not to mention unnecessary, because I was going to embed the dropdown values into this modal window.

What I did was to refactor the javascript app, into php code to fill the values, and left the important webservice requests alone, I didn’t want to use the flXHR library, because the widget was so simple, so what I did was a php json-rpc proxy client, winch its work would be to post the data received from the client to a remote webservice.

I’m using Zend_Json to encode/decode json, because the php version on production is 5.1, and the php json extensions are not available.

First I create an object that will hold the data to be sent.

01
$re = new stdClass();
02
$re->brand_id  = $_POST['brand_id'];
03
$names         = $_POST['domains'];
04
 
05
$domains = explode(",", $names);
06
$filteredDomains = array();
07
foreach ($domains as $domain) {
08
 $domainParts = parse_url($domain);
09
 if (isset($domainParts['host']) && $domainParts['host'] != '') {
10
 $filteredDomains[] = $domainParts['host'];
11
 }
12
}
13
$re->domains   = $filteredDomains;

That was simple, I didn’t have to worry about filtering the user input, because the webservice will take care of that, the only thing I do, is  create an array of domains, with has only the host part.

after I have my Object ready I encode it as a json string, open a socket and make the request, here is how I did it:

01
$request = Zend_Json::encode($re);
02
$opts = array ('http' => array (
03
    'method'  => 'POST',
04
    'header'  => 'Content-type: application/json',
05
    'content' => $request
06
    ));
07
$context  = stream_context_create($opts);
08
$conection = $fp = fopen($url, 'r', false, $context);
09
if ($conection) {
10
 $reply = '';
11
 while($row = fgets($fp)) {
12
 $reply.= trim($row)."\n";
13
}
14
$reply = Zend_Json::decode($reply);

Pretty simple no?