# Desktop \<-\> Web

**URL:** <https://www.ruby-forum.com/t/desktop-web/157825>\
**Category:** Ruby\
**Created:** [January 15, 2009, 6:12pm UTC](https://www.ruby-forum.com/t/desktop-web/157825 "2009-01-15T18:12:05Z")\
**Posts on this page:** 19\
**Page:** 1

<div class="post-metadata">

**Author:** ![tcsnide](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/eb8c5e/32.png) [@tcsnide](https://www.ruby-forum.com/u/tcsnide)\
**Post date:** [January 15, 2009, 6:12pm UTC](https://www.ruby-forum.com/t/desktop-web/157825/1 "2009-01-15T18:12:05Z")

</div>

I want to interface a desktop application to a backend web  
application. What’s the easiest way to go about this --what’s the best  
way to communicate between the two?

Thanks,  
T.

---

<div class="post-metadata">

**Author:** ![tcsnide](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/eb8c5e/32.png) [@tcsnide](https://www.ruby-forum.com/u/tcsnide)\
**Post date:** [January 15, 2009, 6:16pm UTC](https://www.ruby-forum.com/t/desktop-web/157825/2 "2009-01-15T18:16:49Z")

</div>

On Fri, 2009-01-16 at 02:09 +0900, Trans wrote:

> I want to interface a desktop application to a backend web  
> application. What’s the easiest way to go about this --what’s the best  
> way to communicate between the two?

SOAP and XML-RPC are both good options, as is a REST-style interface.  
Net::HTTP on the client, whatever on the server.

---

<div class="post-metadata">

**Author:** ![tcsnide](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/eb8c5e/32.png) [@tcsnide](https://www.ruby-forum.com/u/tcsnide)\
**Post date:** [January 15, 2009, 10:48pm UTC](https://www.ruby-forum.com/t/desktop-web/157825/3 "2009-01-15T22:48:02Z")

</div>

On Jan 15, 2009, at 3:39 PM, Brian C. wrote:

> - soap4r (shudder) is bundled with Ruby

Ruby 1.8. I believe it’s gone in Ruby 1.9.

James Edward G. II

---

<div class="post-metadata">

**Author:** ![tcsnide](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/eb8c5e/32.png) [@tcsnide](https://www.ruby-forum.com/u/tcsnide)\
**Post date:** [January 16, 2009, 6:25am UTC](https://www.ruby-forum.com/t/desktop-web/157825/4 "2009-01-16T06:25:41Z")

</div>

On Thu, Jan 15, 2009 at 10:39 PM, Trans [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> I want to interface a desktop application to a backend web  
> application. What’s the easiest way to go about this --what’s the best  
> way to communicate between the two?

Are you writing the webapp too?

martin

---

<div class="post-metadata">

**Author:** ![tcsnide](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/eb8c5e/32.png) [@tcsnide](https://www.ruby-forum.com/u/tcsnide)\
**Post date:** [January 15, 2009, 10:40pm UTC](https://www.ruby-forum.com/t/desktop-web/157825/5 "2009-01-15T22:40:55Z")

</div>

Aria S. wrote:

> On Fri, 2009-01-16 at 02:09 +0900, Trans wrote:
> 
> > I want to interface a desktop application to a backend web  
> > application. What’s the easiest way to go about this --what’s the best  
> > way to communicate between the two?
> 
> SOAP and XML-RPC are both good options, as is a REST-style interface.  
> Net::HTTP on the client, whatever on the server.

There are APIs on the client side which are higher level than Net::HTTP.

- xmlrpc is bundled with Ruby
- soap4r (shudder) is bundled with Ruby
- ActiveResource is a REST client

Which you use typically depends on what the backend application  
provides. Note that all three use XML, and so are inefficient for large  
binary transfers, as you have to base64 encode them.

If you are writing both front and backend, you could consider other  
protocols (e.g. DRb). That’s harder to scale though, whereas it’s easy  
to set up a HTTP proxy for load-balancing.

The above are all synchronous protocols. If asynchronous semantics suit  
you better (e.g. submit a request, poll for the response later) then you  
could talk to a queuing system, e.g.

- Memcache protocol - Starling
- AMQP protocol - various servers inc RabbitMQ
- Stomp protocol over HTTP - various servers inc Apache ActiveMQ
- … lots of others

Another option is to use XMPP (Jabber) as the transport. There is xmpp4r  
as endpoint, and a selection of XMPP servers to route your messages  
through. xmlrpc can run over XMPP. But this is likely to be overkill for  
a single-server scenario.

Finally, consider seriously the possibility of using a plain web browser  
as the client, using HTML and AJAX over HTTP. It’s maybe a bit harder to  
build an application with a desktop “feel” but it is doable (see Google  
Docs), and you don’t need to distribute any code to the clients.

Rails has particularly good support for this, and can generate most of  
the necessary Javascript for you. However if you’re not already a Rails  
user, there’s a steep learning curve to get there.

---

<div class="post-metadata">

**Author:** ![tcsnide](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/eb8c5e/32.png) [@tcsnide](https://www.ruby-forum.com/u/tcsnide)\
**Post date:** [January 16, 2009, 11:20am UTC](https://www.ruby-forum.com/t/desktop-web/157825/6 "2009-01-16T11:20:05Z")

</div>

On Jan 16, 12:20 am, Martin DeMello [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> On Thu, Jan 15, 2009 at 10:39 PM, Trans [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:
> 
> > I want to interface a desktop application to a backend web  
> > application. What’s the easiest way to go about this --what’s the best  
> > way to communicate between the two?
> 
> Are you writing the webapp too?

yes.

---

<div class="post-metadata">

**Author:** ![tcsnide](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/eb8c5e/32.png) [@tcsnide](https://www.ruby-forum.com/u/tcsnide)\
**Post date:** [January 16, 2009, 12:41pm UTC](https://www.ruby-forum.com/t/desktop-web/157825/7 "2009-01-16T12:41:22Z")

</div>

On Fri, Jan 16, 2009 at 3:48 PM, Trans [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> yes.  
> I’d suggest returning data from the webapp as json, then, and reading  
> it as yaml from the ruby end. I did that in a recent project at work  
> and it was pretty painless. The benefit is if you want to build a rich  
> browser-based frontend later, client side javascript can use the same  
> json objects.

martin

---

<div class="post-metadata">

**Author:** ![tcsnide](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/eb8c5e/32.png) [@tcsnide](https://www.ruby-forum.com/u/tcsnide)\
**Post date:** [January 16, 2009, 1:33pm UTC](https://www.ruby-forum.com/t/desktop-web/157825/8 "2009-01-16T13:33:21Z")

</div>

On Jan 15, 4:39 pm, Brian C. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> to set up a HTTP proxy for load-balancing.  
> as endpoint, and a selection of XMPP servers to route your messages  
> user, there’s a steep learning curve to get there.  
> Thanks Brian. Lots of useful info hear. I actually did create web-  
> browser client at first, but the problem is that I needed to save  
> files to the local file system, and that was just too cumbersome with  
> a web-client --it required that I had a local server running too,  
> which added additional headaches. I considered something like Google  
> Gears, Adobe Air, etc. but that ended real quick when I discovered  
> none of them supported 64bit Linux, which I run.

(Aside Rant: What the hell is going on with 64 bit support btw? Why  
the hell are we stuck in 32-bit world? I mean how long has has it  
bloody been already since 64 CPUs hit the mass-market? It’s just  
intolerable! Honestly, I can’t say enough bad things about this state  
of affairs. It really has to be the pinnacle example of how the whole  
industry has gone to hell in a hand basket.)

So I’m using Shoes on the front-end. And for the most part that’s  
working pretty good so far.

T.

---

<div class="post-metadata">

**Author:** ![tcsnide](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/eb8c5e/32.png) [@tcsnide](https://www.ruby-forum.com/u/tcsnide)\
**Post date:** [January 16, 2009, 2:48pm UTC](https://www.ruby-forum.com/t/desktop-web/157825/9 "2009-01-16T14:48:04Z")

</div>

Thomas S. wrote:

> So I’m using Shoes on the front-end. And for the most part that’s  
> working pretty good so far.

Makes sense.

Some years ago I wrote a system which used DRb over HTTP: I had to  
modify the DRb code slightly to do this (adding support for fastcgi  
server processes). That was nice as it let me use native Ruby objects,  
but if hashes containing just text are OK for you (and make sure they’re  
only ASCII or UTF-8 text), xmlrpc should be fine.

I did come across YAML RPC once; there’s some code floating around on  
the net for that, but it’s possibly stale now.

I don’t know if there’s any sort of standard for “JSON RPC”. I suspect  
it just means REST with JSON response objects. If you want to try that,  
and to keep as close to Rack as possible, then I suggest layering  
something very lightweight like Sinatra on top of it. Of course, Rails  
has render :json. Remember too that json supports _only_ Unicode  
strings, so anything binary needs base64 encoding.

Don’t forget that your backend app will probably need some sort of  
authentication framework, possibly just HTTP Basic Auth for simplicity,  
to stop random clients making requests.

Even if you don’t use a browser as a front-end, you might be able to  
steal some ideas from those who do. e.g.

> **[pure.js - Javascript Template Engine](https://pure-js.com/)**
>
> pure.js is a Javascript template engine providing a radical separation between the representation and the logic

Anyway, that’s just a few random thoughts.

Regards,

Brian.

---

<div class="post-metadata">

**Author:** ![tcsnide](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/eb8c5e/32.png) [@tcsnide](https://www.ruby-forum.com/u/tcsnide)\
**Post date:** [January 16, 2009, 1:21pm UTC](https://www.ruby-forum.com/t/desktop-web/157825/10 "2009-01-16T13:21:35Z")

</div>

On Jan 16, 6:39 am, Martin DeMello [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> I’d suggest returning data from the webapp as json, then, and reading  
> it as yaml from the ruby end. I did that in a recent project at work  
> and it was pretty painless. The benefit is if you want to build a rich  
> browser-based frontend later, client side javascript can use the same  
> json objects.

I thought about this as well, but how did you go about transporting  
the json?

At the moment I’ve taken Aria’s suggestion of using XML-RPC, that’s  
working fine via the XMLRPC::WEBrickServlet. But ultimately I want to  
use Rack instead. An example of a simple Rack-based JSON servlet would  
be awesome. Anyone have one?

T.

---

<div class="post-metadata">

**Author:** ![tcsnide](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/eb8c5e/32.png) [@tcsnide](https://www.ruby-forum.com/u/tcsnide)\
**Post date:** [January 20, 2009, 11:38am UTC](https://www.ruby-forum.com/t/desktop-web/157825/11 "2009-01-20T11:38:47Z")

</div>

P.S. I’m not sure what is the “right” way to serialize Ruby objects in  
JSON.

I took the to\_json and json\_create code from the ruby json library  
documentatation, which gives

```
{"json_class": "name", "data": ["values", ...]}

```

Maybe it would be more natural to serialize a Ruby object as  
{“attr\_name”: “attr\_value”, …}, since { … } itself denotes an  
“object” according to the JSON specification.

However I’ve also seen examples on the web using a hybrid:

```
{"json_class": "name", data: {"attr_name": "attr_value", ... } }
```

---

<div class="post-metadata">

**Author:** ![tcsnide](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/eb8c5e/32.png) [@tcsnide](https://www.ruby-forum.com/u/tcsnide)\
**Post date:** [January 20, 2009, 11:19am UTC](https://www.ruby-forum.com/t/desktop-web/157825/12 "2009-01-20T11:19:00Z")

</div>

Thomas S. wrote:

> ultimately I want to  
> use Rack instead. An example of a simple Rack-based JSON servlet would  
> be awesome. Anyone have one?

How about this with Sinatra, which sits on top of Rack:

— myapp.rb —  
require ‘rubygems’  
require ‘sinatra’  
require ‘json’  
require ‘widget’

get ‘/widgets.json’ do  
Widget.all.to\_json  
end

get ‘/widgets/:id.json’ do  
Widget.find(Integer(params[:id])).to\_json  
end

post ‘/widgets.json’ do  
item = JSON.parse(request.body.read)  
raise “Bad object” unless item.is\_a? Widget  
Widget.add(item).to\_s  
end

— widget.rb —

# Rubbish model, not thread-safe!

class Widget  
attr\_accessor :id, :name, :price  
def initialize(id, name, price)  
@id, @name, @price = id, name, price  
end  
def to\_json(\*a)  
{  
‘json\_class’ =\> self.class.name,  
‘data’ =\> [@id, @name, @price],  
}.to\_json(\*a)  
end  
def self.json\_create(o)  
new \*o[‘data’]  
end  
def self.all  
@all ||= []  
end  
def self.add(item)  
@seq ||= 0  
@seq += 1  
item.id = @seq  
all \<\< item  
return @seq  
end  
def self.create(\*args)  
add(new(\*args))  
end  
def self.find(id)  
all.find { |item| item.id == id }  
end  
end  
Widget.create(nil, “flurble”, 12.3)  
Widget.create(nil, “boing”, 4.56)

---

<div class="post-metadata">

**Author:** ![tcsnide](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/eb8c5e/32.png) [@tcsnide](https://www.ruby-forum.com/u/tcsnide)\
**Post date:** [January 20, 2009, 2:56pm UTC](https://www.ruby-forum.com/t/desktop-web/157825/13 "2009-01-20T14:56:13Z")

</div>

On Jan 20, 2009, at 4:37 AM, Brian C. wrote:

> P.S. I’m not sure what is the “right” way to serialize Ruby objects in  
> JSON.

I think it’s probably better to think of JSON as simple primitives.  
Thus JSON’s “object” would map to Ruby’s Hash. From there, I just  
create an output method that translates my objects to primitives and  
an input method that restores them.

Most libraries do seem to try to dump everything though, so maybe this  
is just flawed thinking on my part.

James Edward G. II

---

<div class="post-metadata">

**Author:** ![tcsnide](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/eb8c5e/32.png) [@tcsnide](https://www.ruby-forum.com/u/tcsnide)\
**Post date:** [January 20, 2009, 3:12pm UTC](https://www.ruby-forum.com/t/desktop-web/157825/14 "2009-01-20T15:12:03Z")

</div>

James G. wrote:

> I think it’s probably better to think of JSON as simple primitives.  
> Thus JSON’s “object” would map to Ruby’s Hash. From there, I just  
> create an output method that translates my objects to primitives and  
> an input method that restores them.

For a POST it seems to make sense to think of JSON as a “params” hash,  
like a form post or an XML-wrapped hash.

Following that logic, PUT ought to be the same, and hence GET. And the  
‘class’ is implicit in the REST URL: /widgets/ or whatever.

OK, I’m sold, for web use anyway. Maybe the documentation in the JSON  
library is a bit misleading then.

---

<div class="post-metadata">

**Author:** ![tcsnide](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/eb8c5e/32.png) [@tcsnide](https://www.ruby-forum.com/u/tcsnide)\
**Post date:** [January 23, 2009, 10:14pm UTC](https://www.ruby-forum.com/t/desktop-web/157825/15 "2009-01-23T22:14:19Z")

</div>

On Jan 20, 10:05 am, Brian C. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> end  
> — widget.rb —  
> h[v.to\_s[1…-1]] = instance\_variable\_get(v)  
> item.id = (@seq += 1)  
> Widget.create(“name” =\> “flurble”, “price” =\> 12.3)  
> Widget.create(“name” =\> “boing”, “price” =\> 4.56)
> 
> If you require ‘json/add/rails’ then you don’t need to define your own  
> to\_json method, but it also allows people to create arbitrary Ruby  
> objects on your machine (which makes me uncomfortable)

Thanks. I’ll give it a go.

T.

---

<div class="post-metadata">

**Author:** ![tcsnide](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/eb8c5e/32.png) [@tcsnide](https://www.ruby-forum.com/u/tcsnide)\
**Post date:** [January 20, 2009, 4:06pm UTC](https://www.ruby-forum.com/t/desktop-web/157825/16 "2009-01-20T16:06:47Z")

</div>

That simplifies things a bit. Here it is for completeness:

— myapp.rb —  
require ‘rubygems’  
require ‘sinatra’  
require ‘json’  
require ‘widget’

get ‘/widgets.json’ do  
Widget.all.to\_json  
end

get ‘/widgets/:id.json’ do  
Widget.find(Integer(params[:id])).to\_json  
end

post ‘/widgets.json’ do  
item = JSON.parse(request.body.read)  
Widget.create(item).to\_s  
end

— widget.rb —

# Rubbish model, not thread-safe!

class Widget  
attr\_accessor :id, :name, :price  
def initialize(params)  
@id = params[“id”]  
@name = params[“name”]  
@price = params[“price”]  
end  
def to\_json(\*a)  
instance\_variables.inject({}) { |h,v|  
h[v.to\_s[1…-1]] = instance\_variable\_get(v)  
h  
}.to\_json(\*a)  
end

@all = []  
@seq = 0  
def self.all  
@all  
end  
def self.add(item)  
item.id = (@seq += 1)  
all \<\< item  
return @seq  
end  
def self.create(params)  
add(new(params))  
end  
def self.find(id)  
all.find { |item| item.id == id }  
end  
end  
Widget.create(“name” =\> “flurble”, “price” =\> 12.3)  
Widget.create(“name” =\> “boing”, “price” =\> 4.56)

If you require ‘json/add/rails’ then you don’t need to define your own  
to\_json method, but it also allows people to create arbitrary Ruby  
objects on your machine (which makes me uncomfortable)

---

<div class="post-metadata">

**Author:** ![tcsnide](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/eb8c5e/32.png) [@tcsnide](https://www.ruby-forum.com/u/tcsnide)\
**Post date:** [January 23, 2009, 10:23pm UTC](https://www.ruby-forum.com/t/desktop-web/157825/17 "2009-01-23T22:23:31Z")

</div>

I also learned from the Sinatra list that there is a Rack middleware  
module you can load which which will perform the parsing of JSON POST  
data for you, so it just ends up in params. Tidy.

[http://groups.google.com/group/sinatrarb/msg/6579132bee5fc0b2](http://groups.google.com/group/sinatrarb/msg/6579132bee5fc0b2)

> <https://github.com/rack/rack-contrib/blob/44322288f263dda0743183529efe4e04a240e76c/lib/rack/contrib/post_body_content_type_parser.rb>

---

<div class="post-metadata">

**Author:** ![tcsnide](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/eb8c5e/32.png) [@tcsnide](https://www.ruby-forum.com/u/tcsnide)\
**Post date:** [January 24, 2009, 4:54pm UTC](https://www.ruby-forum.com/t/desktop-web/157825/18 "2009-01-24T16:54:56Z")

</div>

There’s not much in Halcyon you’ll find beyond what you’ve already  
learned  
here. The interesting bit, I guess, would be the  
PostBodyContentTypeParser  
middleware. Apologies for the name, haha. I wrote the middleware to  
compliment Halcyon since everything coming out of it was JSON I figured  
it  
should at least support it coming in.  
Halcyon behaves very similar to what’s going on in your application…  
essentially it breaks down to a simplistic pattern: always have a  
resource  
(a hash or an array of hashes, for example) to respond with as JSON  
objects.  
A lot of the time it was just calling #to\_json on an object as the body  
of  
the response. Aside from that, everything is as you’d expect.

I recommend JSON wholeheartedly.

Matt

On Fri, Jan 23, 2009 at 10:41 PM, hemant [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> 

–  
Matt T.  
Highgroove Studios  
[www.highgroove.com](http://www.highgroove.com)  
cell: 404-314-2612  
blog: [maraby.org](http://maraby.org)

Scout - Web Monitoring and Reporting Software

> **[Application Monitoring for Ruby, PHP, Node.js, Python, and Elixir ~ Scout](https://scoutapm.com/)**
>
> Rails Monitoring, Django Monitoring, Elixir Phoenix Monitoring, PHP Laravel Monitoring, and more that identifies slow database queries, memory leaks, and slow custom code.

---

<div class="post-metadata">

**Author:** ![tcsnide](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/eb8c5e/32.png) [@tcsnide](https://www.ruby-forum.com/u/tcsnide)\
**Post date:** [January 24, 2009, 4:46am UTC](https://www.ruby-forum.com/t/desktop-web/157825/19 "2009-01-24T04:46:10Z")

</div>

On Sat, Jan 24, 2009 at 2:51 AM, Brian C. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> I also learned from the Sinatra list that there is a Rack middleware  
> module you can load which which will perform the parsing of JSON POST  
> data for you, so it just ends up in params. Tidy.
> 
> [http://groups.google.com/group/sinatrarb/msg/6579132bee5fc0b2](http://groups.google.com/group/sinatrarb/msg/6579132bee5fc0b2)
> 
> [rack-contrib/lib/rack/contrib/post\_body\_content\_type\_parser.rb at 44322288f263dda0743183529efe4e04a240e76c · rack/rack-contrib · GitHub](http://github.com/rack/rack-contrib/blob/44322288f263dda0743183529efe4e04a240e76c/lib/rack/contrib/post_body_content_type_parser.rb)

If sole purpose is to ferry back JSON back forth, one may have a look  
at:

[http://halcyon.rubyforge.org/](http://halcyon.rubyforge.org/)

Also, why bother converting JSON to YAML on ruby side? Marshalling  
Ruby objects to JSON is equally easier. If you are using AR or  
something it already has support for that, otherwise JSON gem already  
comes with support for marshalling built-in types which can be easily  
extended to custom classes with to\_json method.
