1. #1
    Ext User
    Join Date
    Jan 2008
    Posts
    14
    Vote Rating
    0
    dombroskib is on a distinguished road

      0  

    Default Ext.Direct - why

    Ext.Direct - why


    I don't want to seem like a naysayer, but I am perplexed at the interest or desire to use or develop Ext.Direct. RPC methodologies have come and gone in the past (COBRA, RPC Web methods, etc) and most have fallen to the side of mainstreet development practises for contract driven development. IMHO RPC lends itself to a wild wild west type of development. Where does security get applied? Logging? Auditing? Standards? How scalable is it?

    With a little thought and planning the 'ease' that developers are looking to gain from Ext.Direct can be achieved in the previous versions of Ext without coupling the client side code directly to server side code.

    After several projects with Ext we have refactored and settled in on a recent project with the following goals

    - A single entry point to all JSON calls into the middleware. This will allow us to control, process and append new requirements at the message level in the future without going and touching code in xxx methods. Once alll the preprocessing is done the entry point will route the request to the correct business object. Once the business object is done, the entry point will apply post processing logic (auditing, logging, etc) and returns to the caller.

    - To accommodate the first requirement a common AJAX request signature is needed...we ended up with Format (JSON or XML), Domain, Message, Version, object. Domain is not a web domain, it is a Business Domain, for example Membership. An example of a message in the Membership domain would be "CancelMembership" and the version "1.0"

    - Client side rendering restricts application features based upon authorizations, BUT server side security must also apply restrictions based upon the same authorizations...after all we really don't trust what comes from the web. This is easy to implement because we have our single entry point and every request will have a Domain and Message that we can apply authorizations against. This is implemented in a authorization preprocessor.

    - Server side developers will NOT need to configure xml files or modify code to get their method to process a request, instead they simply have to decorate methods and classes with attributes and that alone will have their class/method participate in the message processing.

    Since we all love code, here is some sample code of what we ended up with. We are a MSFT shop and have c# code, but the patterns can be implemented in any backend OO language. It has definitelt increased our productivity as there is little to do to implement a new message/business logic.

    The below code is how the server side developer decorates their method with attributes
    Code:
    [MessageProcessorRegistration("Membership","CreateAccount","1.0")]
    publicvoid AddAccount(MessageRequestContext ctx)
    {
     
    }
    The below code is how the server side developer return their message results
    Code:
    [MessageProcessorRegistration("Membership","CreateAccount","1.0", )]
    public void AddAccount(MessageRequestContext ctx)
    {
    ...
    ctx.Response = objectReturnedWithID;
    }

    The below code snippet is how the client side developer would make a JSON/AJAX call, the key is everyone uses the RodomRuntime.ProcessRequest
    Code:
    this.AddMember= function() {
    var member = //Build some type of new member object here 
    RodomRuntime.ProcessRequest("JSON", "Membership", "CreateAccount", "1.0", member, this.ProcessAddMemberResults, this.AddMemberFailure);
    }
    
    Ok, so you are asking how is this better?

    KISS! It is very SIMPLE. All the pieces and parts are already in Ext, we just needed to apply a few simple well proven design patterns.

    Maintainable and Extendable
    We are now in the process of extending the server side method attributes to include Cacheability. If a method has cacheability set we will first call out to memcache to see if a ctx.Reponse already exists. The cacheability attributes control who, how and when something is cacheable.

    We have added a new preprocessor for scability that allows us to direct the request off to a MOM hub (we are using ActiveMQ) that allows us to scale the request processing to as a large of a scale as the back end datastore will support.

    To reduce the number of client/server roundtrips we are looking at the ability to submit and process multiple messages in a single request from the client (think mashup and application startup time).

    We can support new versions of the same message for backwards compatability.

    Wow, I just hit preview, and this is a long rant. I guess what it comes down to is that Ext.Direct, although nice, I don't think it really fits into a usable enterprise feature. Anyone else have the same thoughts or am I missing the point completely?

  2. #2
    Ext JS Premium Member dj's Avatar
    Join Date
    Mar 2007
    Location
    Germany
    Posts
    573
    Vote Rating
    2
    dj has a spectacular aura about dj has a spectacular aura about dj has a spectacular aura about

      0  

    Default


    As far as I understand Ext.Direct (and I'm using it already with a Ruby on Rails project I'm working on right now) Ext.Direct is merely a frontend for the server backend. You could easily write a provider for Ext.Direct that fits your .NET-backend. Ext.Direct is not another RPC mechanism.
    Ext.Direct is a tool to transparently use a RPC of your choosing in your frontend code. It is integrated in Ext.data.* so you e.g. could configure your Stores and Records to automatically persist any changes that were made on them automatically. So – to continue your example – adding a new member can be written as:
    Code:
    var memberStore = Ext.StoreMgr.lookup('member-store');
    var newMember = new memberStore.recordType({
      // the data for the new member
    });
    memberStore.add(newMember);
    This will add a new (phantom in Ext-terms) item to the store. It is instantly visible on the client side and will be automatically persisted (and realized in Ext-terms) if you had configured the member store with an api config and a writer config.
    Daniel Jagszent
    dɐɳiel@ʝɐgszeɳt.de <- convert to plain ASCII to get my email address

  3. #3
    Sencha User
    Join Date
    Mar 2008
    Posts
    19
    Vote Rating
    2
    serff is on a distinguished road

      0  

    Default


    I haven't used Direct yet, but wanted to share a few thoughts. One really cool thing about Ext.Direct is how it will bundle multiple requests into a single request to the server. That in itself is very powerful in terms of reducing the amout of traffic between the browser and server. We still have a lot of questions about how an enterprise Direct provider will really work and also how the polling/long polling providers will work, but if you were just starting off a project and needed to rapidly get things going, Direct is very powerful and quick.

    Anyway, that's my quick two cents. If you have questions about the request bundling, let us know

  4. #4
    Ext JS Premium Member christocracy's Avatar
    Join Date
    Oct 2006
    Location
    Montreal
    Posts
    381
    Vote Rating
    0
    christocracy is on a distinguished road

      0  

    Default


    Being a Rails/Merb guy, I like how talking to my models in Firebug is like script/console or bin/merb -i

    Code:
    >Users.find({sort: "ASC"});
    >Users.destroy(1);
    >Users.create(rec.data);
    There's really not much to it. Ext.Direct routes Ajax requests through a single pipe and queues multiple requests into one.

    It's much better than salting this throughout your code:
    Code:
    onCreate : function(rec) {
        Ext.Ajax.request({
            url: '/users/create/',
            method: "POST",
            params: {
                record: Ext.encode(rec.data)
            },
            success : function(response) {
                var res = Ext.decode(response.responseText);
                if (res.success === true) {
                     // do good stuff
                }
                else {
                    // do bad stuff
                }
            },
            failure : function() {
                // do really bad stuff
            }
        });
    },
    onDestroy : function(rec) {   
        Ext.Ajax.request({
            url: '/users/destroy/' + rec.id,
            method: "POST",
            success : function(response) {
                var res = Ext.decode(response.responseText);
                if (res.success == true) {
                      // do good stuff.
                }
                else {
                    // do bad stuff
                }
            },
            failure : function(response) {
                // do really bad stuff
            }   
        });
    }
    Ugh. Ext.Direct condenses your server-side communication and frees you to work on more important issues.

    (Rails people: See this )
    /**
    * @author Chris Scott
    * @business www.transistorsoft.com
    * @rate $150USD / hr; training $500USD / day / developer (5 dev min)
    *
    * @SenchaDevs http://senchadevs.com/developers/transistor-software
    * @twitter http://twitter.com/#!/christocracy
    * @github https://github.com/christocracy
    */

  5. #5
    Sencha - Community Support Team edspencer's Avatar
    Join Date
    Jan 2009
    Location
    Palo Alto, California
    Posts
    1,939
    Vote Rating
    9
    edspencer is a jewel in the rough edspencer is a jewel in the rough edspencer is a jewel in the rough

      0  

    Default


    Quote Originally Posted by christocracy View Post
    Code:
    >Users.find({sort: "ASC"});
    >Users.destroy(1);
    >Users.create(rec.data);
    To use this practically I guess you'd need to do something more like this?:

    Code:
    User.find(1, {
      success: function(user) {
        //do something with the user object
      },
      failure: function() {
        //show a message that the User couldn't be found
      }
    });
    And the same for create and destroy. Or am I missing something here?
    Ext JS Senior Software Architect
    Personal Blog: http://edspencer.net
    Twitter: http://twitter.com/edspencer
    Github: http://github.com/edspencer

  6. #6
    Ext JS Premium Member christocracy's Avatar
    Join Date
    Oct 2006
    Location
    Montreal
    Posts
    381
    Vote Rating
    0
    christocracy is on a distinguished road

      0  

    Default


    Not quite.
    The last param is simply success f'n.
    Handle failure at the pipe, listening to Ext.direct, not on your data-object.

    Code:
    Users.destroy(1, function(result, response){
        alert(response.message);
        If (response.status===false) {
            // failed to destroy 
        }
    );

    });
    /**
    * @author Chris Scott
    * @business www.transistorsoft.com
    * @rate $150USD / hr; training $500USD / day / developer (5 dev min)
    *
    * @SenchaDevs http://senchadevs.com/developers/transistor-software
    * @twitter http://twitter.com/#!/christocracy
    * @github https://github.com/christocracy
    */

  7. #7
    Sencha User
    Join Date
    Dec 2008
    Location
    Lodz, Poland
    Posts
    173
    Vote Rating
    3
    grzegorz.borkowski is on a distinguished road

      0  

    Default


    Well, I have similar mixed feeling about Ext.Direct. I prefer to expose server-side through REST interface. Client code written in Ext can simply use this REST API by sending appropriate GET,POST,PUT,DELETE methods. This is extremely simple conceptually, easy to test, and works very well. It adds a bit of coding overhead in front perhaps, but the architecture and design are so clear and easy to follow, that the maintanance boost is significant.
    I'm not sure if appying Ext.Direct would add any advantages here... I've tried to use DWR (kind of Ext.Direct ancestor?) earlier but then I've switched to REST style, and it made the application developement and maintenance far far easier...
    One interesting point is chaining the requests for performance. On the other hand, this requires that there are really many requests send: say 5 requests per second. Well, it's hard to imagine for me that the user could do so many operations in so short time: update one record, add another one, and delete yet another one in less than one second? I'm not so sure about it...

  8. #8
    Sencha - Architect Dev Team aconran's Avatar
    Join Date
    Mar 2007
    Posts
    9,266
    Vote Rating
    121
    aconran is a splendid one to behold aconran is a splendid one to behold aconran is a splendid one to behold aconran is a splendid one to behold aconran is a splendid one to behold aconran is a splendid one to behold aconran is a splendid one to behold

      0  

    Default


    Quote Originally Posted by grzegorz.borkowski View Post
    One interesting point is chaining the requests for performance. On the other hand, this requires that there are really many requests send: say 5 requests per second. Well, it's hard to imagine for me that the user could do so many operations in so short time: update one record, add another one, and delete yet another one in less than one second? I'm not so sure about it...
    How about a grid which users are able to edit a bunch of records at once and then click a button and hit save?

    Or an alternate situation, how about on the initial page load you are loading/executing several different methods and they are all batched together in a single request.

    Just a few thoughts of places I've seen this really come in handy.
    Aaron Conran
    @aconran
    Sencha Architect Development Team

  9. #9
    Ext JS Premium Member dj's Avatar
    Join Date
    Mar 2007
    Location
    Germany
    Posts
    573
    Vote Rating
    2
    dj has a spectacular aura about dj has a spectacular aura about dj has a spectacular aura about

      0  

    Default


    Hi grzegorz,

    Ext.Direct and a RESTful interface can be combined. It should be quite easy to write a new provider that connects to your RESTful interface. But with this RESTful provider the request batching is of course not possible. Request batching is a feature of the RemotingProvider not Ext.Direct per se.

    Even without users on crack I have some use cases where request batching is quite useful. E.g. I often use ComboBoxes with relative few items to do some key-value lookup in an (Editor)Grid. On rendering of the grid I load the data of a grid and all stores in one batch.

    Code:
        afterRender: function(){
            this.channelStore.load(...);
            this.mediaTypesStore.load(...);
            this.store.load(...);
            App.VideoPanel.superclass.afterRender.apply(this, arguments);
        }
    That way I can work with the ComboBox stores in 'local'-mode ...
    Code:
                    {
                        xtype: 'combo',
                        valueField: 'id',
                        displayField: 'name__en',
                        name: 'channel_id',
                        store: this.channelStore,
                        triggerAction: 'all',
                        mode: 'local',
                        editable: false
                    }
    ... since I know that the store was loaded when the grid data is there.
    Daniel Jagszent
    dɐɳiel@ʝɐgszeɳt.de <- convert to plain ASCII to get my email address

  10. #10
    Sencha - Community Support Team edspencer's Avatar
    Join Date
    Jan 2009
    Location
    Palo Alto, California
    Posts
    1,939
    Vote Rating
    9
    edspencer is a jewel in the rough edspencer is a jewel in the rough edspencer is a jewel in the rough

      0  

    Default


    Quote Originally Posted by aconran View Post
    How about a grid which users are able to edit a bunch of records at once and then click a button and hit save?

    Or an alternate situation, how about on the initial page load you are loading/executing several different methods and they are all batched together in a single request.

    Just a few thoughts of places I've seen this really come in handy.
    Hmm that's interesting actually - one of the problems we run into time and again is a form with one or more combo boxes which need to be populated from the server. For example you might have a form which updates a Product which contains a drop-down to select a Category for the product.

    For this form you need to make two requests - one to get the Product data and another to grab the list of Categories. You don't know which one will finish first so sometimes the combo box will populate correctly and sometimes it won't.

    It sounds like this is a possible solution for that particular problem. There may be better ways of doing it, but I've not seen one It becomes more handy the more of those requests you have to do for a form.

    I'll check it out... I don't think it's something to automatically apply everywhere grzegorz.borkowski, but I can see its uses now
    Ext JS Senior Software Architect
    Personal Blog: http://edspencer.net
    Twitter: http://twitter.com/edspencer
    Github: http://github.com/edspencer