Blog.

Mastering Ext.Direct, Part 2

Code in this post can be obsolete, however, principles and theory may still apply.

<<< Mastering Ext.Direct, Part 1

Adding server-side classes

After completing part 1, we have the basic setup running. Although Ext.Direct PHP stack example classes are fine for demonstrating the functionality we will need our own PHP classes in the real life. I’m not going to explain basics of PHP object oriented programming, anyway, there is a couple of things to point out.

Let’s create (useless) class Car from part1. For that, create file classes/Car.php with the following content:

<?php
// vim: sw=4:ts=4:fdc=4:nospell
    class Car {
        /**
          * @remotable
          */
        public function start() {
            return "Started";
        } // eo function start

        /**
          * @remotable
          */
        public function go($speed) {
            return "The speed is $speed";
        } // eo function go

        /**
          * @remotable
          */
        public function stop() {
            return "Stopped";
        } // eo function stop

        public function repair() {
            return "Done";
        } // eo function repair

    } // eo class car
// eof

Then edit api.php and add Car to $api->add() call so that it reads:

// ...
$api->add(
    array(
        'Echo' => array('prefix' => 'Class_'),
        'Exception' => array('prefix' => 'Class_'),
        'Time',
        'File',
        'Car'
    )
);
// ...

Reload index.php and type in Firebug console:

Example.Car.start();

You should get the following response:

{"type":"rpc","tid":2,"action":"Car","method":"start","result":"Started"}

Now type:

Example.Car.repair();

Error, yes? Why? Take a deeper look at Car source code. Some methods have comments

        /**
          * @remotable
          */

but repair does not have it. And that is the single reason why it is not exported to API so it is not known to the client application. You can verify it by typing:

Example.API.actions.Car;

in Firebug console.

If you want to know how is it done study ExtDirect_API PHP class in classes/API.php file and ReflectionClass documentation. In any case, it makes our life very easy as we only need to:

  • write server side classes
  • add the above comment to the methods that can be called remotely

Can it be simpler?

Returning values

Type in Firebug console:

console.log(Example.Car.start());

Now you see that the return value of the call is undefined despite of the fact that server side method returns string "Started". This leads us to a very important note:

Ext.Direct calls are ASYNCHRONOUS.

That means that the code execution does NOT wait until the call is finished but it immediately continues. So never try to use the return value, neither assume that you have data available at the line that follows the call.

The value returned from the server side method call is wrapped in the request response and it arrives when it arrives. It can take milliseconds or seconds depending on the connection speed, server execution time and other factors.

I will discuss response processing in the next part

Exceptions

Edit go method of our Car class so that it reads:

        /**
          * @remotable
          */
        public function go($speed) {
            if(0 >= $speed || 200 < $speed) {
                throw new Exception("Speed must be between 0 and 200");
            }
            return "The speed is $speed $unit";
        } // eo function go

and execute:

Example.Car.go(300);

You get the following response:

{"type":"exception","tid":3,
"message":"Speed must be between than 0 and 200",
"where":
"#0 [internal function]: Car->go(300)n
#1 /ddata1/devel/learnfromsaki.com/direct/ExtDirect/Router.php(176): call_user_func_array(Array, Array)n
#2 /ddata1/devel/learnfromsaki.com/direct/ExtDirect/Router.php(62): ExtDirect_Router->rpc(Object(stdClass))n
#3 /ddata1/devel/learnfromsaki.com/direct/router.php(23): ExtDirect_Router->dispatch()n
#4 {main}"}

You see that the response type changed from rpc (remote procedure call) to exception and the response contains member message that is the text of the Exception we’ve thrown at server side. So far so good, however, where member contains debugging data that, while useful for debugging, shouldn’t be disclosed in a production environment.

You can freely throw exceptions while debugging your Ext.Direct application but you should consider another method(s) of handling errors for production systems. I will tackle it again later in this series.

Combining requests

Type the following:

Example.Car.start();Example.Car.go(80);Example.Car.stop();

The request is:

[
{"action":"Car","method":"start","data":null,"type":"rpc","tid":4},
{"action":"Car","method":"go","data":[80],"type":"rpc","tid":5},
{"action":"Car","method":"stop","data":null,"type":"rpc","tid":6}
]

and the response is:

[
{"type":"rpc","tid":4,"action":"Car","method":"start","result":"Started"},
{"type":"rpc","tid":5,"action":"Car","method":"go","result":"The speed is 80"},
{"type":"rpc","tid":6,"action":"Car","method":"stop","result":"Stopped"}
]

Ext.Direct combines requests that come within a configurable time frame into one to minimize the server round trips count.

Conclusion

Now we know a couple of basics:

  • we need to export API from server to client – Ext.Direct stack does a lot of dirty work for us
  • we can call server side methods directly at client prefixed with a configurable namespace (Example in our case)
  • we cannot use return values of client calls because calls are asynchronous
  • to add classes we need to add them to $api->add() call and add /** @remotable */ comments to methods
  • multiple requests and responses are combined in one if they come fast enough

Mastering Ext.Direct, Part 3 >>>

saki
Follow me:
Latest posts by saki (see all)

3 Responses

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Enter your username and password to log into your account. Don't have an account? Sign up.

Want to collaborate on an upcoming project?