Ext.Direct and JSON server based on Zend

Ext.Direct and JSON server based on Zend

In this post you will find some information about how to connect Ext.Direct with Zend, the most popular framework for php developers. If you don’t know what Ext.Direct is and what possibilities gives us when we use it in our Ext JS 4 application, just look on official Sencha website. This knowledge is necessary if you want get deeply into solution, which I will show you here.

Communication protocols

In every web app we need a tool/platform which will helps us communicate easily with backend. The most popular way is to build web services like SOAP or JSON servers.
In first, data are package in XML, second use native javascript format JSON (JavaScript Object Notation). It’s hard to say which of them is better. It depends on what you want to achive. SOAP server give us possibility to define schema in file called WSDL, which will be used to automaticlly validate incoming messages. In JSON server we need to take care about that writing proper part of code. However huge advantage is in the size of sent data, JSON is a lot lighter and less complicated format. And in the end you can decode it faster and easier to useful form.
On post purpose I will use second solution based on JSON format.

CRUD

Before we will start with Ext.Direct and ZF itself, we need to explain what it’s CRUD.
So, in few words, it’s acronym for create, read, update, destroy, four basic functions of persistent storage.  Why is so important to know about it? Because both of layers (frontend and backend) of our app will use this mechanism (in Ext JS every model can be created, loaded/read, updated and destroyed so we need to replicate this behavior on server side).  Of course we will be able to add more function to our server but for each object that represent data we will implement CRUD firstly.

Ext.Direct and ZendFramework

In this post we will use source code available on our github:

get files from repository

To work with, you need to clone it via git and configure virtual host on your apache server. You can do this like for standard ZF application (if you don’t know how, look at this topic on stackoverflow). Ok, if app runs without problem, we are able to start.
To connect two worlds, frondend and backend we need two things. First, it will be a map of method generated by json server, second, will be provider, a javascript class which will read all of necessary information and will convert it to the object and method on client side. In our case is called ZendFrameworkProvider, but should be working with all web services following json-rpc 2.0 specs.

zfp

First step is to register provider class in Ext.Direct manager:

Ext.require(
    [
        'Ext.direct.*',
        'MyApp.lib.direct.ZendFrameworkProvider'
    ], function () {
        Ext.direct.Manager.addProvider(
            //Ext.app.REMOTING_API
            {
                'type': 'zf',
                'url': Ext.app.JSONRPC_API.target,
                'actions': Ext.app.JSONRPC_API.services,
                'format': 'json'
            });
    });

To complete this task we need to use Ext JS loader. As first parameter array of required classes will be passed (line 3,4) and as second we will put callback  (line 5-14) where we add our provider to direct manager object.
To be clear in line 9 we can find shortcut for provider class alias (fully: “direct.zfprovider“).
Line 10 is endpoint on which we will send data.
Line 11 is an object with all methods which are available on server side.

You can find above code in app.js:

zfp2

As I mention earlier to communicate between client and server Ext.Direct need something like a map/list of methods. In our case it is generated by server, picture below show where it can be found.

zfp3

As we see we got two types of file. One, with php extension, generate mappings dynamically on every request, so can be used for development stage. Second, js, keeps last output from first one and can be used for production.

Example map below:

Ext.define('Ext.app.JSONRPC_API', { // name of class
    "transport": "POST", // http method
    "envelope": "JSON-RPC-2.0", // server specification
    "contentType": "application\/json", // type of response
    "SMDVersion": "2.0", // generated map version
    "target": "\/api\/json\/1.0\/jsonrpc.php", //our endpoint url
    "services": { // declaration of services available on server
        "Game.Player.read": { // service name
            "envelope": "JSON-RPC-2.0",
            "transport": "POST",
            "parameters": [ // arguments for it
                {
                    "type": "array",
                    "name": "params",
                    "optional": false
                }
            ],
            "returns": "array"
        },
        "Game.Player.create": {
            "envelope": "JSON-RPC-2.0",
            "transport": "POST",
            "parameters": [
                {
                    "type": "array",
                    "name": "params",
                    "optional": false
                }
            ],
            "returns": "array"
        },
        "Game.Player.update": {
            "envelope": "JSON-RPC-2.0",
            "transport": "POST",
            "parameters": [
                {
                    "type": "array",
                    "name": "params",
                    "optional": false
                }
            ],
            "returns": "array"
        },
        "Game.Player.destroy": {
            "envelope": "JSON-RPC-2.0",
            "transport": "POST",
            "parameters": [
                {
                    "type": "array",
                    "name": "params",
                    "optional": false
                }
            ],
            "returns": "array"
        }
    },
    "singleton": true
});

As we see, code above is a Ext JS singleton class. It’s important to remember that we need to put link to this declaration before our application scripts (for details look to /public/index.html).

Ok, we configure everything on client side, now we need to look deeper and analyze our backend stuff. Example class for json server can be found here:

zfp4

If we have nearby a little knowledge about php, understanding content of it shouldn’t be a problem for us. Only two conditions exist to make it work, we need declare method as public and we should include some docblock annotation with description of parameters and returned data. As example method “read“:

/**
     * @param array $params
     * @return array
     */
    public function read($params)
    { // methods will return object with players array
        return array(
            'success'=>true,
            'Player'=>array(
                array(
                    'id' => 0,
                    'name' => 'Sebastian',
                    'surname' => 'Widelak',
                    'age' => 24,
                    'nickname' => 'mkalafior'
                ),
                array(
                    'id' => 1,
                    'name' => 'Gal',
                    'surname' => 'Anonim',
                    'age' => 999,
                    'nickname' => 'anonymous'
                )
            )
        );
    }

To be honest, structure of returned data is important too. We need to have key “success” on which Ext.Direct will decide if response was successful. Information which we want to returned need to be stored under another key (it’s not important how you named it as long as you put same name in Ext JS store/model).

Last thing that we need to know is how to configure client side models and stores. Usually we should have same models/tables representation on both side. In above code we can consider that one of the returned array under “Player” key is our backend model. For Ext Js it will be looks like this:

Ext.define('MyApp.model.Player', { //name of class
    extend: 'Ext.data.Model',
    fields: [ //fields definition
        { name: 'id', type: 'integer' },
        { name: 'name', type: 'string' },
        { name: 'surname', type: 'string' },
        { name: 'age', type: 'integer' },
        { name: 'nickname', type: 'string' }
    ],
    proxy : {
        type : 'direct', // we need to configure proxy type
        api : { // and define api
                // thx to CRUD it shouldn't be a problem
            read : Game.Player.read,
            destroy : Game.Player.destroy,
            create : Game.Player.create,
            update : Game.Player.update
        },
        // next we need to define type of reader
        reader : {
            // as json
            type : 'json',
            // and set root key under which data are stored in server response
            root: 'Player'
        }
    }
});

Application configured in this way should allow us to use all of Ext.Direct features . Of course, above text is only small introduce how to us this technique. I will show you more in my next post, so be patient.

Comments:

Leave a Reply

Please fill all required fields


Drag circle to the rectangle on the right!

Send