Working with JSON RPC from javascript

JSON-RPC is lightweight remote procedure call protocol similar to XML-RPC. Its very simple and its used by alots of web applications at least json wich is very used in modern applications.

To communicate with server in a professional way, json-rpc is a good solution all you need to do is to create server side classes and pass it to an json rpc server class like Zend_Json_Server, read the documentation about how to create the server side.

For the client side you need to create a javascript class witch sends the request to the server and parse the response.

The json request for json-rpc is very simple has three properties in the json object: the method, params and request id.

{method : "Account.login", params : ["user","pass"], id : "194" }

And response contain the result of call, the error if it is, and the request id number.

{"result": "done", "error": null, "id": "194"}

The id of the request and response is used to  match the request and reponse of the current call. For example if you send a request and also add a listener for it, when the response comes call the listener with the specific id. This id is increasing at every request.

I made a simple json-rpc implementation for javscript that handle a json-rpc protocol. Sintax of using this rpc implementation is very simple, its provide a fluent call mode with two functions “call” and “done”.

Rpc.call("Account.login", "username", "password").done( onLoginResponse );

This Rpc class depends by a public json encoder/decoder class, you can find this class here. For this work you must to change the url from ajax call and changed to your url, and thats all.

var Rpc = {
		id   : 0,
		cid  : 0,
		callbacks:[],
		call : function()
		{
			var args = [];
			
			for(var i=0;i<arguments.length;i++)
				args.push(arguments[i]);
			
			var method;
			var tosend;
			this.id++;
			this.cid = this.id;
			
			if(args.length)
			{
				method = args.shift();

				var tosend = {method : method, params : args, id : this.cid };

				jQuery.ajax({
					async: true,
					contentType: 'application/json',
					type: 'POST',
					processData: false,
					dataType: 'json',
					url: '/api/js',
					cache: false,
					data: JSON.stringify(tosend),
					error: function(req,stat,err){
						Boxy.alert(err);
					},
					success: function(data){
						for(i=0;i<public.Rpc.callbacks.length;i++)
						{
							if(public.Rpc.callbacks[i])
							if(public.Rpc.callbacks[i].id == data.id)
							{
								var callback = public.Rpc.callbacks[i].callback;
								
								if(callback)
								{
									callback.apply(null, [data.result]);
									public.Rpc.callbacks.splice(i,1);
								}
							}
						}
					}
				});
			}
			
			return this;
		},
		
		done   : function(callback)
		{
			if(typeof(callback) == 'function')
			this.callbacks.push( { id : this.cid, callback : callback } );
		}
};

Leave a Comment.