OverviewThe Javascript binding, like other Etch language bindings, aims to allow developers a way to access Etch-based services in a manner which is as natural to the developer as possible. Ideally, this means that by simply looking at an Etch IDL, one should be able intuit how one would invoke the methods of such a service with understanding just a few simple conventions. Since most developers speak code, let's look at some examples of what this really means for Javascript. Consider a simple, server-directed add method defined in an Etch IDL file: @Direction(server) int add(int arg1, int arg2) Then we consider how one would invoke that method in a Javascript script: svc.add({ arg1: 1, arg2: 2, onSuccess: function(returnValue) { alert ("Got a result: " + returnValue); }, onError: function(error) { alert("failure"); } }); Using the above example, let's take a second to talk about how a method in an Etch IDL translates into a Javascript method. The svc variable in the above snippet is the object which represents the client-side reference to the service. There are just a few lines of boilerplate service initialization not shown here, but all one needs to know is that every method associated with the Etch service is represented as a function on this svc object, such as the add method defined in the Etch IDL above. The next convention in use here is that each argument is passed into the method as a named parameter. In this example, that's the arg1: and arg2:. If we had omitted arg1, arg2, or both, nulls would have been passed to the server for those omitted values. Finally, every server-directed method support a onSuccess and onError argument, which expect you to pass a function. These functions serve as callbacks that are fired once the method has completed. The onSuccess callback is invoked if the operation completed successfully. Passed back as the only argument to this onSuccess callback is the return value of the method (if void is the return then no argument is passed). The onError callback is invoked if the operation did not complete successfully; for instance, if the method threw an exception, or if communication was interrupted between client and server on that method call. Note that we use callbacks instead of the return value of the svc.add method because Javascript is implemented as a single-threaded language in every browser. This thread is shared between the browser UI and the Javascript script code, so we must not block the browser waiting on a response from the server. IdealsThere are a number of considerations one must make when dealing with browsers, Javascript, and the web in general. The ideals below represent the general mindset and direction of the binding. At this point in time, these ideals are not necessarily fully implemented.
Mapping Etch IDL to JavascriptEvery Etch IDL construct should have a intuitive analogy in Javascript. This section details those mappings. Server-directed methodEtch IDL @Direction(server) int add(int arg1, int arg2) Javascript svc.add({ arg1: 1, arg2: 2, onSuccess: function(returnValue) { alert ("Got a result: " + returnValue); }, onError: function(error) { alert("failure"); } }); Server-directed method that uses structsEtch IDL module etch.examples service Calculator { struct Values { int arg1, int arg2 } struct AddResult { int addResult } @Direction(server) AddResult add(Values toBeAdded) } Javascript var values = new etch.examples.Calculator.Values(); values.arg1 = 1; values.arg2 = 2; svc.add({ toBeAdded: values, onSuccess: function(returnValue) { // returnValue instanceof etch.examples.Calculator.AddResult == true alert ("Got a result: " + returnValue.addResult); }, onError: function(error) { alert("failure"); } }); Server-directed method with exceptionEtch IDL module etch.examples service Calculator { exception OverflowException { string message } @Direction(server) int add(int arg1, int arg2) throws OverflowException } Javascript svc.add({ arg1: 1, arg2: 2, onSuccess: function(returnValue) { alert ("Got a result: " + returnValue); }, onError: function(error) { if(error instanceof etch.examples.Calculator.OverflowException) { alert("Overflow exception. Message: " + error.message); } } }); Client-directed methodEtch IDL /** Example method server tells client about some state change */ @Direction(client) void stateChange(string username, boolean online) Javascript svc.callbacks.stateChange = function (username, online) { // define your custom logic in this method, to indicate // what happens when the server invokes 'stateChange' } Client-directed method with a returnEtch IDL /** Example method server tells client about some state change, client acks it */ @Direction(client) boolean stateChange(string username, boolean online) Javascript svc.callbacks.stateChange = function (username, online) { // because stateChange defines a boolean return, we should return a value return true; } Client-directed method that defines an exceptionEtch IDL /** Example method server tells client about some state change, client can throw exception */ module etch.examples service Chat { struct NotSupportedException { string reason } @Direction(client) boolean stateChange(string username, boolean online) throws NotSupportedException } Javascript svc.callbacks.stateChange = function (username, online) { // say we want to let the server know that this client does not support // the stateChange callback var notSupported = etch.examples.Chat.NotSupportedException(); notSupported.reason = "Not currently supported."; throw notSupported; } Current State
Roadmap
|