Search code examples
apache-flexremoting

How to separate remote object and interface in Flash Builder Flex


The code below shows interface and remote object are coded in the same file How to separate them into two files ?

Current Code :

    <s:RemoteObject id="ro"
                    destination="customerService" 
                    source="customerService" 
                    endpoint="http://localhost/amfphp/gateway.php"
                    showBusyCursor="true">
        <s:method name="getCustomer" result="getCustomer_resultHandler(event)">
            <s:arguments>
                <CusOpt>{''}</CusOpt>
                <option>{''}</option>
                <idcompany>{2}</idcompany>
            </s:arguments>
        </s:method>
        <s:method name="genPKID" result="genPKID_resultHandler(event)">
            <s:arguments>
                <idcompany>{2}</idcompany>
            </s:arguments>
        </s:method>
    </s:RemoteObject>   

Wrong way of doing :

import mx.rpc.remoting.RemoteObject;


    public class CustomerRO extends RemoteObject
    {
        public function CustomerRO(destination:String=null)
        {
            super(destination);
            this.destination = "customerService";
            this.source = "customerService";
            this.endpoint = "http://localhost/amfphp/gateway.php";
            this.showBusyCursor = true;
        }
    }

Solution

  • You want to create a client-side service stub for your remote service. There's a few steps to get this set up properly.

    Create the service interface

    For brevity we'll create an interface with just one method, but you can add as many as you need.

    package be.vmm.user.service {
        import mx.rpc.AsyncToken;
    
        public interface ICustomerService{      
            function getCustomerById(id:int):AsyncToken;        
        }
    }
    

    Create an implementation of the interface

    In your example you are extending RemoteObject. I would suggest you encapsulate it: that would be a lot more flexible. Not to mention that in your code the connection information is hardcoded which requires you to recompile your application every time this info changes.

    public class CustomerService implements ICustomerService {
        private var ro:RemoteObject;
    
        public function CustomerService(ro:RemoteObject) {
            this.ro = ro;
        }
    
        public function getCustomerById(id:int):AsyncToken {
            return ro.getCustomerById(id);
        }
    
    }
    

    You also have the option to create another implementation of the interface. The most common use case consists of creating a mock service that doesn't really connect to the server but returns fake data directly. If you want to test your application without server connection you can now just substitute your real service stub with the mock service stub, since they both implement the same interface.

    Use the implementation

    var ro:RemotObject = new RemoteObject();
    ro.destination = "customerService";
    ro.source = "customerService";
    ro.endpoint = "http://localhost/amfphp/gateway.php";
    ro.showBusyCursor = true;
    //these properties are best externalized in a configuration file
    
    var service:ICustomerService = new CustomerService(ro);
    var token:ASyncToken = service.getCustomerById(1);
    token.addResponder(new Responder(handleResult, handleFault));
    
    private function handleResult(event:ResultEvent):void {
        //do what you need to do
        trace(event.result as Customer);
    }
    
    private function handleFault(event:FaultEvent):void {
        //show error message
    }