Processing JSON-RPC 2.0 request parameters

Last week I updated the JSON-RPC 2.0 Base library with a set of utility classes to assist programmers with the processing of request parameters. This updated version is numbered 1.6 (2010-02-18).

The new utility classes solve three common issues that occur when processing request parameters:

  • Provide type correct retrieval of the JSON parameter values.
  • Differentiate between mandatory and optional parameters.
  • Produce an appropriate JSON-RPC 2.0 error on a missing or invalid parameter.

These points are best illustrated with a concrete example. Consider the following RPC request signature. The parameters are specified by name, as key-value pairs packed into a JSON object (called named parameters). The other way to specify the parameters is by position, by packing the values into a JSON array (called positional parameters). The parameters are of three different types (JSON string, JSON number and JSON true/false), where the first two are mandatory and last one is optional (defaults to false).

method: "makePayment"
named parameters:
	"recipient"    : string, mandatory
	"amount"       : number, mandatory
	"confirmation" : boolean, optional (defaults to false)

Let’s now create a JSON-RPC 2.0 request for the above method. Using the JSON-RPC 2.0 Base API this is as simple as

// The requested method
String method = "makePayment";

// The request ID
int id = 0;

// The named parameters
String recipient = "Penny Adams";
double amount = 175.05;
Map params = new HashMap();
params.put("recipient", recipient);
params.put("amount", amount);

// Create a new request
JSONRPC2Request request = new JSONRPC2Request(method, params, id);

To serialise the request to a JSON string just use the toString() method

String json = request.toString();

which will produce the following output (pretty formatting mine):

{
  "method"  : "makePayment",
  "params"  : { "amount" : 175.05, "recipient" : "Penny Adams" },
  "id       : 0,
  "jsonrpc" : "2.0"
}

Then, on the server side, the received JSON string is parsed back to a request object, which is then dispatched to the appropriate handler depending on the requested method name.

try {   
        request = JSONRPC2Request.parse(json);
} catch (JSONRPC2ParseException e) {
        // handle parse error ...
}

String method = request.getMethod();
// ... dispatch request to appropriate handler based on method name ...

Within the handler we can now proceed with extracting the request parameters. The utility package provides three Java classes for that:

Since the makePayment method expects named parameters (key-value map) we need to create a new NamedParamsRetriever.

// Check if we got named/JSON object params
if (request.getParamsType() != JSONRPC2ParamsType.OBJECT) {
        // Report params type error...
}
Map params = (Map)request.getParams();
NamedParamsRetriever np = new NamedParamsRetriever(params);

Now we proceed by retrieving the request parameters according to their type.

The retriever methods for mandatory parameters have the form

[return-type] getXXX(String name)

where XXX is the expected parameter type and name specifies the parameter, e.g.

boolean  getBoolean(String name)
int      getInt(String name)
float    getFloat(String name)
String   getString(String name)
...
String[] getStringArray(String name)
...

These methods will throw an JSONRPC2Error.INVALID_PARAMS if the parameter is missing or its type doesn’t match the expected. You can use this ready error object to create the appropriate JSONRPC2Response straightaway.

For optional parameters, such as “confirmation” in our example, we use methods that will return the specified default value if it isn’t set in the received request. They have the form

[return-type] getOptXXX(String name, [return-type] defaultValue)

where XXX is the expected parameter type, name specifies the parameter and the last argument the default value, e.g.

boolean  getOptBoolean(String name, boolean defaultValue)
int      getOptInt(String name, int defaultValue)
float    getOptFloat(String name, float defaultValue)
String   getOptString(String name, String defaultValue)
...
String[] getOptStringArray(String name, String[] defaultValue)
...

These methods will throw an JSONRPC2Error.INVALID_PARAMS only if the parameter’s type doesn’t match the expected.

The PositionalParamsRetriever class has similar methods, except that they accept an integer argument specifying the parameter’s position.

So, let’s proceed with the actual code now.

// Extract parameters
try {   
        // Extract mandatory "recipient" parameter
        String recipient = np.getString("recipient");

        // Extract mandatory "amount" parameter
        double amount = np.getDouble("amount");

        // Extract optional "confirmation" parameters, defaults to false
        // if undefined
        boolean confirmation = np.getOptBoolean("confirmation", false);
} catch (JSONRPC2Error err) {
         // If a mandatory parameter is missing or there is a type mismatch
         // you get a ready JSON-RPC 2.0 error object which you can use
         // to construct the appropriate response
         return new JSONRPC2Response(err, id);
}

Note that if a retrieval method fails, it will throw a ready JSONRPC2Error object which you can use to form the server’s response.

Look at the JavaDocs to see a list of all types the retriever classes support. They include all primitive types such as boolean, int and float as well as more complex types such as enumerated strings, key-value maps and arrays of primitives and strings.

Links:

JsWorld 1.4

I’ve just updated the JSWorld library to the latest world locale data derived from Unicode‘s CLDR 1.7.2 (released December 2009). The current JSWorld version is now 1.4.

You can purchase a license and download JSWorld 1.4 from here.

A newer JSWorld version is already planned and work should soon begin on it if all goes well. It will add methods to parse formatted currency amounts, numeric amounts and data/time strings.

Finally, huge thanks to the many people who contribute to the Unicode’s ongoing CLDR process of keeping an up-to-date database of the world’s various locales!

Apache Directory Studio

Recently I was evaluating various free LDAPv3 servers to store the profiles of TransactionCenter users. Apache DS was among the candidates. I did give their server a try and it seemed to fit my product’s purposes. But the greatest and most useful discovery on the Apache’s directory project website was their LDAP browser. I don’t know whether this is just a side-project or not, but I’ve been using it for 3+ months now and I can now say that this is the best LDAP client tool I have come across. And I have used a number of such software, free as well as commercial. Huge thanks to its creators!

Give it a try: Apache Directory Studio.

The client packs a lot of functionality so the GUI may appear a bit cluttered at first. But once I got used to it I trashed all other LDAP clients I had on my computer.

Apache Directory Studio
Apache Directory Studio

JSON-RPC 2.0 Software Updates

Today I released slightly updated versions of my JSON-RPC 2.0 software implementations – the minimalist “Base” Java package as well as the sister console client package.

This web protocol seems to be gradually receiving more attention, but adoption is still relatively slow. My explanation for this lag is that designing and coding your own ad-hoc JSON-based data interchange scheme is quite easy. There are, however, good reasons to consider the more standardised approach:

  • If you have an environment with multiple applications and services using JSON to pass data, adopting a single standard protocol among them can make maintenance, interconnectivity and deployment of new web applications easier.
  • If you provide services to the web or sell web-related software, offering a standard interface can make your product more attractive to clients.
  • Finally, why reinvent the wheel? The JSON-RPC protocol is well tested and relatively settled now, and there’s existing software for it too.

If you need help, the central JSON-RPC forum is at http://groups.google.com/group/json-rpc

Една нощ под връх Бездивен

Най-гостоприемните хора живеят високо горе в планината. Петък вечерта с колегата Ножаров замръкнахме точно на билото до връх Бездивен, където с повече съобразителност и немалко извънземен късмет попаднахме на единствените живи хора в района, последното семейство животновъди в иначе изоставена махала. Та тези хора не само че предложиха да ни приютят за през нощта, но и ни приготвиха царска вечеря и закуска, че и с подаръци ни изпратиха дори! И макар да имаше езикова бариера помежду ни си изкарахме една невероятна вечер. Единствено съжалявам за другите такива планинци, които ги няма там сега, отчуждени и изгонени от нашата страна. До т.нар. “възродителен процес” в околността са живели 19 семейства.

По въжения мост между селата Дъждовница и Сухово
На яз. Кърджали срещи полуострова на крепостта Патмос
Изгрев над колибите на Бездивен където нощувахме при овчарите
Спускането от връх Бездивен към долината
Над река Боровица

На първа планинска с велоклуб Крива спица

Отпечатано в октомврийския брой на сп. Туризъм и Бизнес. Текст: Владимир Джувинов. Снимки: Владимир Джувинов, Владимир Русев, Росен Попов, Стефан Андонов

На Дяволския мост
На Дяволския мост

Пореден напън над педалите. Колелото едва пълзи нагоре по стръмната горска пътека. На първа планинска скорост съм, по-леки предавки не останаха, а краката ми вече са омекнали като разварени спагети. “Ще се бута май”, чувам аз колегата до мен. Това обаче никак не ни плаши. Всъщност, бутането е една съвсем рутинна част от планинското “колоездене”. Виж, мъкненето на колелото на гръб нагоре по сипей осеян с поддаващи камъни – това вече може би е неприятност!

Дърветата се разтварят и нашата вело дружина излиза в светлината на приказна поляна огряна от лятното слънце. Спираме да си поемем дъх, докато очите попиват гледката. Някъде там долу в равнината се вижда града. Суетата и забързаността на ежедневието обаче изглеждат толкова далечни и незначителни сега. Не мисля за нищо, усещам единствено как свежия горски вятър гали разгорещеното тяло. И се чувствам щастлив.

Всеки любител на планинското колоездене си има своята предистория. Аз се захванах преди пет години, главно за разтоварване, особено след някой психо ден на работа. Купих си добре запазено колело втора ръка за 160лв. и започнах да карам из близките гори и баири. Аз и преди обичах да обикалям планините и веднага установих, че колелото има две значителни предимства пред ходенето пеша. Първото е най-вече практично, а именно че на две гуми за един ден могат да се покрият в пъти повече разстояния и следователно забележителности. Второто откритие – това беше голата емоция от скоростта и хвърчането по пътеките, нещо което бързо се превръща в страст. Носете си каска обаче!

Напредъкът по принцип идва постепенно. На мен в началото дори късите наклончета по гладко шосе ми се виждаха мъчителни. Но само след няколко месеца редовно каране започнах да усещам, че вече мога да се справям с все по-дълги и тежки карания. Година по-късно се престраших да участвам в двудневен 200км велопоход в компанията на по-опитен приятел от фирмата. Това беше едно незабравимо изживяване, което ни преведе през гори, езера и китни селца (а може би трябва да добавя и кръчмите). След него вече бях изцяло спечелен за каузата планински колоездач.

На момчетата от пловдивската “Крива спица” попаднах благодарение на модерното чудо интернет. Дотогава чумеех предимно сам из планината, което вече беше започнало да ми дотяга. Нуждаех се от компания. Затова каква радост беше да открия сродни души – както за летене по горските пътеки, така и за миговете на философска равносметка и релакс на по бира в края на деня.

Всеки неподправен любител на планинското колоездене може да намери местенце при “Кривите спици”, независимо какво точно го кара да потегли с колелото нагоре към гората – дали срещата с природата, спускането на скорост по игриви пътечки, епичните приключения в други измерения, или просто бирата с качамак на финала. Важни са удоволствието и споделеният миг!

Освен карания и излети през свободните дни, “Крива спица” също така провежда по две култови мероприятия през годината. В началото на лятото за приятели на клуба се организира “Перпендикулярна вселена” – четиридневен велопоход, който всяка година отвежда участниците до някои от най-красивите и потайни места на Родопите. През септември пък е време за 24-часовия маратон по планинско колоездене, състезание за доказване на мускулите и волята, където в продължение на един ден и една нощ се навъртат километри по пресечен терен.

* * *

Уеб сайт и форум на “Крива спица”: www.kriva.org

Клубът се събира в Пловдив, всеки четвъртък от 19:30ч в Трабанта (до Коматевски възел)

Високо в Рила
Високо в Рила. Всички планини в България са малко или повече достъпни за колоездене, стига да разполагате с достатъчно кондиция, карачески умения и не на последно място – воля за преодоляване на предизвикателства.
Катеренето с колело, особено когато има неравности и хлъзгав терен, изисква солидна мускулна тяга. При върхови усилия се изгарят по 1000 калории/час и дори повече.
Downhill Крива спица
Карачът, който знае как да си партнира със земното притегляне, може да се превърне в спускаческа машина преодоляваща невероятни препятствия. За да няма играчка-плачка, защитата на главата и тялото са задължителни тук.
Крива спица, Стара планина
По билото на Балкана. За каране из такива места човек трябва да е подготвен за среща с всички планински елементи.
Крива спица, Бездивен
Над язовир Кърджали в Родопите. Колелото е универсален метод за планински туризъм, който позволява изминаване на не малки разстояния – с добро темпо от порядъка на 50 до 100км на ден.
Маратон "24"
“Крива спица” провежда две от най-култовите мероприятия по планинско колоездене през годината - “Перпендикулярна вселена”, многодневен велопоход из най-красивите кътчета на Родопите, както и състезанието “24”, денонощен планински веломаратон за проверка на най-издръжливите.
Крива спица, Таратор
След тежкия ден е време за почивка и раздумка. Наред с бирата, тараторът има солидно присъствие в менюто на “Кривите спици”.