Hi, I would like to turn some of our simulation codes out to pasture and string some of them together by draping them in web services. I''m looking for a RESTful Camping tutorial to get started ... pointers appreciated. Some simple example applications: airfoil force calculator: feed it an airfoil geometry, an angle of attack, and a Mach number, and it returns the lift, drag, and pitching moment ablation: feed it surface temperature and thermal protection material properties, and it returns surface blowing rate and specie mass fractions. Thanks, -- Bil Kleb http://fun3d.larc.nasa.gov
Someone asked:> Are you looking for a REST tutorial, or are you already familiar with > REST and just want to know how to use it with Camping?I am barely familiar with both REST and Camping, and I''d like to explore some RESTful Camping as a way to learn both. Kleb wrote:>> Some simple example applications: >> >> airfoil force calculator: feed it an airfoil >> geometry, an angle of attack, and a Mach number, >> and it returns the lift, drag, and pitching momentWhere for the sake of argument, the "airfoil force calculator" is a executable on a *nix box that currently swallows input from standard input and dumps results to standard output. Later, -- Bil Kleb http://fun3d.larc.nasa.gov
On 28-Apr-07, at 1:39 PM, Bil Kleb wrote:> Someone asked: >> Are you looking for a REST tutorial, or are you already familiar with >> REST and just want to know how to use it with Camping? > > I am barely familiar with both REST and Camping, and I''d like > to explore some RESTful Camping as a way to learn both. >With regards to rest, the rails community has more tutorials. Infact, there is a peepcode screencast: http://nubyonrails.com/articles/2006/10/09/peepcode-rest-basics It also includes a free, rails specific, cheat sheet. From the perspective of services using your camping app, one of the most important things (as I understand it) is the URL of the action. The cheat sheet includes a table which matches up some rails methods with HTTP predicates and paths and software actions. With regards to implementing it in Camping... This thread includes discussion about getting Camping to recognize other predicates http://www.mail-archive.com/camping-list at rubyforge.org/msg00029.html Otherwise, some problems with using semicolons to access different aspects ( http://code.whytheluckystiff.net/camping/ticket/118 ) which is, according to the people talking there, a rails-ish thing anyways. Hope this helps, Caleb ps: is the airfoil calculator going to be publicly available...? :)> Later, > -- > Bil Kleb > http://fun3d.larc.nasa.gov > > _______________________________________________ > Camping-list mailing list > Camping-list at rubyforge.org > http://rubyforge.org/mailman/listinfo/camping-list
=begin> I am barely familiar with both REST and Camping, and I''d like > to explore some RESTful Camping as a way to learn both.i still don''t know exactly what REST is (maybe there is no exact definition), part of it is mapping of methods to URIs for a HTTP RPC camping makes playing with all this easy some "REST" examples i see involve query strings, but these can become rather ugly and unreadable/hackable in camping you may do something like =end module Aero::Controllers class Foil < R ''/foil/([^/]+)/([^/]+)/([^/]+)'' def get geo, angle, mach # do some math here and return results end end =begin the last line in the ''get'' method is implicitly returned, it can be text, or a call to a view method.. you would do something like GET /foil/1/90.000/3 in this case, or perhaps query string is more your type: GET /foil?mach=3&angle=37.000 =end class Foil def get lift = input.mach * input.angle # etc end end =begin i think the ST of REST stands for "state transfer" - which is more accurate and easy in JSON than query-string vars: in JS+jQuery: function rpc(o) { $.ajax($.extend({ url : ''/foil'', type : "post", contentType: ''application/json'', dataType : ''json'', data:$.toJSON({mach: 3, forces: [0.00024, 1.33343, 6.777156]}), processData: false, beforeSend: function(xml) { xml.setRequestHeader("Accept", "application/json"); } },o)) } in camping: =end class Foil def post @mach, @f = input.mach, input.forces end end end module Aero def service *a if @method == "post" and @env.CONTENT_TYPE == ''application/json'' @input = JSON.parse(@in.read) end super *a end end =begin and now you can share any object between ECMAscript and Ruby, as long as you stick to floats, ints, strings, arrays, hashes.. what business does your REST server have generating HTML anwyays? its there just to provide calculating service.. =end module Aero::Controllers class Foil def post @headers[''Content-Type''] = @env[:HTTP_ACCEPT] # do some heavy lifting {:lift => lift, :drag => drag, :pitch => pitch}.to_json end end end =begin because you set ''dataType'' to ''json'' in jQuery''s AJAJ options, you get the object passed to the success callback: rpc({success: function(r){ $("#yaw").text(r.pitch * r.skew) }}) this gives you an overview of 1 old fashioned (querystring) 1 camping-fashioned (custom URIs defined via regex) and 1 neo-classical (JSON RPC via post) means to REST while camping. i''ve skipped over POST and HTML forms. since its identical to querystring except the string is in the POST body instead of appended to the URL. ive also skipped custom methods (you could ''def foil'' in your controller if you only wanted it to respond to FOIL requests intead of GET requests) which may be useful if you dont want your app to appear to work to RFC compliant web browsers.. cheers! and happy camping. =end
Caleb Buxton wrote:> > With regards to implementing it in Camping... > > This thread includes discussion about getting Camping to recognize > other predicates > > http://www.mail-archive.com/camping-list at rubyforge.org/msg00029.htmlI had managed to find that (searching for "restful camping" is tricky), but I didn''t make much sense of it yet...> Otherwise, some problems with using semicolons to access different > aspects ( http://code.whytheluckystiff.net/camping/ticket/118 ) which > is, according to the people talking there, a rails-ish thing anyways.Which is apparently gone for Rails 2.0: http://pragdave.pragprog.com/pragdave/2007/03/change_to_rest_.html> Hope this helps,Yes, thank you.> ps: is the airfoil calculator going to be publicly available...? :)Yes, if I can muscle my way past our layers of red tape. Thanks again, -- Bil Kleb http://fun3d.larc.nasa.gov
carmen wrote:> > i still don''t know exactly what REST is (maybe there is no exact definition),I suppose the definitive source is one of the few PhD dissertations that are worth something (mine wasn''t): http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm> camping makes playing with all this easyThat was my hypothesis, nice to have confirmation...> module Aero::Controllers > class Foil < R ''/foil/([^/]+)/([^/]+)/([^/]+)'' > def get geo, angle, mach > # do some math here and return results > end > end > > [..] > > you would do something like GET /foil/1/90.000/3 in this case, > > or perhaps query string is more your type: > > GET /foil?mach=3&angle=37.000Simple enough, thanks.> [..] > > this gives you an overview of 1 old fashioned (querystring) 1 camping-fashioned > (custom URIs defined via regex) and 1 neo-classical (JSON RPC via post) means > to REST while camping. [..]You lost me with most of this, as I am not a hard-core web programmer, but it is comforting to see the similarities in the different tacks. Thanks again, -- Bil Kleb http://fun3d.larc.nasa.gov
Just to chime in, this is related-but-not-quite, I''ve been working off and on on a little library for Rails-style RESTful controllers. It''s called "Sleeping Bag": http://code.google.com/p/sleepingbag It''s not quite ready yet, so don''t expect it to work well, but I thought maybe someone would find it interesting. It basically just maps HTTP actions and the stuff in the path to methods on your controllers. You could have a controller like this: class Planes < R ''/planes'', ''/planes/([^\/]+)'', ''/planes/([^\/]+)/([^\/]+)'' include SleepingBag def index @planes = Plane.find(:all) render :planes_index end def show(id) @plane = Plane.find(id) render :show_plane end end "GET /planes" and "GET /planes/747" are mapped to the index and show methods, respectively, based on the methods'' arity and the fact that index and show are defined by default to be "standard actions", those represented by just an HTTP method, not an aspect. (I''m doing aspects without semicolons, like Rails now is.) Aspects and other standard methods are defined by defining methods, mapped to GET by default. So, to continue with the Planes controller... def wingspan(id) @plane = Plane.find(id) render :plane_wingspan end This would map to "GET /planes/747/wingspan". To fly a plane: methods[:fly] = [:post] def fly(id) @plane = Plane.find(id) @plane.fly! "Bon voyage!" end This means that only "POST /planes/747/fly" will call the fly action. I want to make declaration of controllers simpler, like this: class Planes < ZZZ def index # ... end # ... end Coming soon, possibly... -- Michael Daines