Ringobot log - RingoJS IRC channel: #ringojs on irc.freenode.net
2010-06-08:
[7:03] <hannesw> so earl this is your proposal:[7:03] <hannesw> http://gist.github.com/429711
[7:04] <hannesw> where all simple action functions will only handle GET
[7:05] <hannesw> i must say i prefer the explicit version
[7:05] <hannesw> two levels of inconsistence i see with this:
[7:07] <hannesw> 1. plain functions only handling GET - why? - that's a conceptual inconsistency imo
[7:09] <hannesw> 2. actions files mixing functions and method hashes - that's kind of a visual/app level inconsistency induced by this
[7:09] <hannesw> at least for ringo code, I'd prefer to go 100% method hashes - the added clarity is worth the two extra curlies
[7:13] <oberhamsi> not sure i'm following: we still have simple action functions, but they are catch all.
[7:13] <oberhamsi> and the question is, should we remove plain action functions at all?
[7:13] <hannesw> earl proposed to have simpel functions only catch GET, and (maybe) introduce a ANY or _ pseudo method
[7:13] <hannesw> it should be in the IRC log
[7:14] <hannesw> i.e. optimize for the common case
[7:15] <hannesw> see bottom of http://ringojs.com/bot/2010-06-07
[7:15] <oberhamsi> i'm not a big fan. i like how currently you can write simple functions and still do everything
[7:15] <oberhamsi> (i read, but your 2. is also true for what we currently have - mixing functions & obj literals)
[7:16] <hannesw> yes, but at least for our code, i propose we go method hashes 100%
[7:16] <oberhamsi> okay for our code, i get it
[7:16] <hannesw> for exactly that reason, and i don't care about added stuff - that's actually a plus for me, looking at the code
[7:17] <hannesw> and i expect app writers would probably follow that
[7:17] <hannesw> and catching any with plain functions just makes more sense to me
[7:18] <oberhamsi> makes more sense to my helma-brain as well
[7:18] <hannesw> in helma, we also had foo_action_get etc, but it was rarely used
[7:32] <oberhamsi> we started using those more lately. especially the _post and _xmlrpc
[7:34] <hannesw> that's great. i was semi expecting you'd say "what's that, never heard of it" :)
[7:37] <oberhamsi> haha true couple months ago
[8:48] <hannesw> ah ok:
[8:48] <hannesw> if (response != null) {
[8:48] <hannesw> return (String) response;
[8:48] <hannesw> }
[8:48] <hannesw> das muss es sein
[8:49] <hannesw> aber noclassdeffounderror deutet darauf hin, dass der classpath nicht ok ist, irgendein jar fehlt oder so
[8:51] <hannesw> sorry, wrong window :)
[11:21] <earl> agreed about the visual inconsistency
[11:21] <earl> i don't agree that adding code is a plus, though
[11:22] <earl> i don't think that riddling the common case with complexity ever is a plus
[11:23] <hannesw> earl: your old code will still work exactly as before
[11:24] <earl> it's not the old code that worries me
[11:24] <earl> it's exactly what you are suggesting above
[11:24] <hannesw> it's just that you now have to possibility to be more precise about what you're serving, and imo that's a plus
[11:24] <earl> using this as the default for webapps bundled with ringo
[11:24] <earl> yes, i like the added precision of defining get-only methods
[11:25] <earl> and as i mentioned before, as that's the common case by a very wide margin, i'd like to optimise code structure towards that
[11:25] <earl> and not induce the added {GET: ...} overhead for 80%+ of all webapp functions
[11:26] <earl> will have to think a bit more about how to achieve that in a visually appealing and consistent way, though
[11:28] <earl> what where the reasons for abandoning a config-based approach?
[11:30] <hannesw> it just doesn't make a lot of sense putting this stuff into config, does it?
[11:31] <earl> i don't see that?
[11:32] <hannesw> then try to convince me why it's better
[11:33] <earl> in the config we specify what action handles an URL
[11:34] <hannesw> or better, just go and build something, like I did
[11:34] <earl> seems like a natural place to also specify what methods are handled by the action
[11:34] <hannesw> i didn't know i liked this scheme before i actually tried it out
[11:34] <hannesw> now i'm fully convinced this is the way to go
[11:34] <earl> not much use for me building anything, then, eh :) ?
[11:34] <hannesw> why not?
[11:34] <earl> as you're fully convinced
[11:35] <hannesw> just show me the code, if it's good, we'll implement it
[11:35] <hannesw> for example, just convert some app to the scheme you favour, or write a new app
[11:37] <hannesw> so, looking forward to a gist or something.
[11:38] <earl> http://gist.github.com/429900
[11:38] <hannesw> thanks
[11:39] <hannesw> i thought about that
[11:39] <earl> but i'd do it w/ explicit config doing the wiring
[11:39] <hannesw> problem is: how do you avoid upload_get being called with GET, POST, ...?
[11:39] <hannesw> but it also has to work without explicit config.
[11:40] <earl> nope, i don't think it has to
[11:40] <hannesw> well mapping some space to a module has to work
[11:41] <earl> well, taking that constraint as a given bascially precludes any config-based approach
[11:41] <hannesw> yes, that's a problem
[11:46] <earl> the reason behind this requirement is app-nesting as done in the demo app, is it?
[11:47] <hannesw> no - that's generally the best way to write a webapp, isn't it?
[11:47] <earl> that's a weak argument
[11:48] <hannesw> h?h?
[11:48] <earl> to me, the generally best way to write a webapp is where i require as little lines of code as possible
[11:48] <hannesw> yes. so that's why. do we have a disconnect here?
[11:48] <earl> so yes, i can agree to this argument, but then the very same argument also kills the GET-hash stuff
[11:50] <earl> leaving that aside, it seems that you just don't want config
[11:50] <earl> ok
[11:50] <earl> so config only for mapping an url space to a module
[11:50] <hannesw> just show me working code
[11:52] <earl> ok, updated the gist
[11:52] <earl> [ '/upload', './actions', 'upload', {methods: ['GET', 'POST']} ],
[11:53] <earl> another possibility would be to have two separate routes, and less magic
[11:54] <hannesw> fourth element in url mapping would be action argument i think
[11:54] <hannesw> so we don't have any room for extension there
[11:54] <earl> ok, would probably be a good opportunity to move the third and any following argument into an object
[11:55] <earl> i don't think that's an issue
[11:55] <earl> [ '/upload', './actions', 'upload_get', {methods: ['GET']} ]
[11:55] <earl> [ '/upload', './actions', 'upload_post', {methods: ['POST']} ]
[11:55] <hannesw> i don't see how {methods: ['GET', 'POST']} gets translated into _get and _post suffixes
[11:56] <earl> well, actionname + '_' + method
[11:57] <earl> but maybe that's too much magic alreay anyway, that's why i also added the more explicit mapping
[11:57] <hannesw> and what about the other actions, do they get any method or just GET?
[11:58] <earl> just GET
[11:58] <hannesw> so you have to write a url mapping for each post request
[11:58] <earl> true
[11:59] <earl> hmm
[12:00] <hannesw> I guess I'm just in love with the method hash. it does what sinatra does, only much righter
[12:01] <earl> only that sinatra is concise and ringo is verbose
[12:01] <hannesw> wrong
[12:01] <hannesw> look at this bug report:
[12:01] <hannesw> https://sinatra.lighthouseapp.com/projects/9779/tickets/274-requests-for-same-route-different-request_method-should-return-http-405
[12:01] <hannesw> and look at the comments for how hard it is to implement in sinatra
[12:02] <earl> how hard it is to implement what?
[12:02] <earl> 405 instead of 404?
[12:02] <hannesw> with ringo, you just send a 405 with Object.keys(action) as Allow: header
[12:02] <hannesw> find the allowed methods
[12:02] <earl> really, i couldn't care less how much work the framework has to do
[12:03] <hannesw> and: it's not verbose! there's just two curlies and one level of indentation
[12:03] <earl> that's the very definition of verbose
[12:03] <hannesw> but people have auto-indenting editors nowadays don't they?
[12:03] <earl> uselass boilerplate code
[12:03] <hannesw> that's not boilerplate, you're defining an action for GET requests
[12:03] <earl> yeah, and IDEs that generate hundreds of lines of code with a single click
[12:03] <hannesw> how is that boilerplate?
[12:03] <earl> that's boilerplate if that's what i want to do 80% of the time
[12:04] <earl> in sinatra that's not a single line of additional code
[12:04] <hannesw> GET {} is boilerplate?
[12:04] <earl> yes
[12:04] <hannesw> cmon
[12:04] <hannesw> then sinatra's get '/' is boilerplate too, right?
[12:04] <earl> how so?
[12:04] <hannesw> you can still define an action that handles all methods!
[12:04] <hannesw> it's about equally long
[12:05] <hannesw> actually one character more
[12:05] * robi42 entering the flamewar arena
[12:05] <earl> yes, you can write a big switch
[12:05] <hannesw> gotta leave soon for junior swimming lesson...
[12:05] <robi42> http://gist.github.com/427546 is reasonably close to sinatra (and relatively concise)
[12:06] <earl> yes
[12:06] <earl> i'm rewriting http://gist.github.com/429711 to a more visually consistent version
[12:06] <hannesw> robi42 it's too verbatim a translation, it's not JS but translated ruby
[12:07] <robi42> true, we should stick to finding the best JS-y solution
[12:08] <hannesw> gotta go, back online in half an hour or so
[12:09] <earl> http://gist.github.com/429927
[12:09] <earl> lovely
[12:10] <robi42> earl, it is!
[12:10] <robi42> default routing to GET there?
[12:10] <hannesw> why upload['GET']?
[12:10] <earl> precisely
[12:10] <hannesw> could be just upload.GET
[12:10] <earl> also fine
[12:11] <earl> or even upload.get
[12:11] <robi42> even more concise ;)
[12:11] <earl> (updated to .GET and .POST)
[12:13] * oberhamsi likes it
[12:13] * robi42 likes it, too
[12:13] <hannesw> well the function actions only taking GET requests is not right IMO
[12:13] <hannesw> i don't like it, but you can write it that way if you want to
[12:14] <earl> and off to your swimming lesson you are :)
[12:14] <earl> this can wait. we'll continue chatting later
[12:14] <hannesw> cu
[12:18] <earl> i think function actions defaulting to GET only is the main feature
[12:19] <earl> what's missing is some way for an action to handle all methods
[12:20] <earl> that will need some synthetic key. `._default` or `._any` or sthg like that
[12:27] <robi42> or even `._` as mentioned before
[12:32] <earl> while _i_ certainly like that, i can also see how that's probably too concise to leash on the unwitting general public :)
[12:32] <earl> unleash, even
[12:33] <earl> and unprepared instead of unwitting
[12:33] <earl> well! :)
[12:33] <robi42> :)
[13:02] <hannesw> back
[13:03] <hannesw> earl the thing i don't understand is: functions getting all methods was ok before, why is it not ok now?
[13:03] <hannesw> it's still the obvious solution IMO
[13:05] <hannesw> you can still code your non-method aware apps like you did before
[13:12] <earl> it sure is ok now as well
[13:13] <earl> i don't have strong preferences regarding this point
[13:14] <hannesw> I'll be in vienna tomorrow evening - friday morning
[13:14] <hannesw> maybe we can shake this out over a beer (or five)
[13:15] <earl> buf if method-ignorant actions are ok and the default, i don't see the point in changing all our ringo-bundled apps
[13:15] <earl> i.e. if we want to keep the default, i wouldn't touch/change our current GET actions
[13:16] <earl> if you feel the desire to make all our current actions GET-only, then i'll take that as a hint that we should reconsider the default
[13:16] <earl> and yeah, a beer or five would be fine :)
[13:17] <robi42> a beer or five ftw :)
[13:19] <hannesw> well it's not that the current form is terrible IMO
[13:19] <hannesw> we can leave it as is
[13:19] <hannesw> i think it really depends on your app
[13:19] <hannesw> if you're doing something REST style, you do want to be method aware
[13:20] <hannesw> our apps aren't REST style
[13:21] <earl> yes
[13:22] <hannesw> btw just to protect my online reputation, i couldn't drink 5 beers in a row if i wanted
[13:22] <earl> well, you stand to be corrected :)
[13:23] <earl> i think it's mostly about what we want to assume about the "typical" app
[13:23] <earl> for our webapps, rejecting non-GETs where they are of no use is "nice", but nothing more
[13:24] <earl> would be something different if we can do early rejection of a request right after the headers have been received
[13:24] <earl> or maybe even based on the request line
[13:25] <earl> i.e. don't even try to read a 2MB POST to a action only handling GET
[13:26] <hannesw> well the 2mb post isn't read unless you access req.params anyway
[13:26] <hannesw> (i think at least)
[13:26] <earl> not even by jetty?
[13:27] <hannesw> not sure
[13:27] <earl> well, i think it'll keep the connection open and buffer whatever it receives
[13:27] <earl> anyway
[13:27] <robi42> yet, one could also intercept things like that within some jsgi middleware, right?
[13:28] <hannesw> robi42: complicated, and what's the problem really?
[13:28] <earl> depends if you have the routing information avail in the middleware
[13:28] <hannesw> well, i think i overshot a bit when i wanted to convert all our apps
[13:28] <robi42> in fact, anyway :)
[13:29] <hannesw> maybe it was because i was surprised how much i liked the method hash code :)
[13:29] <earl> :)
[13:32] <hannesw> so do we agree about 1. but not 2. as asked in this posting
[13:32] <hannesw> http://groups.google.com/group/ringojs/browse_frm/thread/c3d8f0afc6c1b4ad
[13:32] <hannesw> ?
[13:32] <hannesw> i.e.: 1: yes, 2: no
[13:33] <hannesw> sorry, i mean this one: http://groups.google.com/group/ringojs/tree/browse_frm/thread/c3d8f0afc6c1b4ad/fe601fff460ded5b?rnum=1&_done=%2Fgroup%2Fringojs%2Fbrowse_frm%2Fthread%2Fc3d8f0afc6c1b4ad%3F#doc_b17eac68f2e3dd7c
[13:33] <robi42> 1
[13:35] <robi42> as in "yes, let's stick with that and not convert all actions in our existing apps to it"
[13:38] <earl> yes
[17:41] <b41l3y> Hi All- When I receive a Post via RIngoJS I'm having a hard time locating the parameters that come along with the post. I thought they would be located here: request.params but on print out of the request object I am not seeing a "params" var at all. Any suggestions?
[18:01] <earl> b41l3y: assuming your action is using `request` as argument name, the parameters should indeed be available as `request.params`
[18:28] <b41l3y> thnx earl. it is named "request". we were printing out the full request obj but cant see the params var. but if we do a print on request.params alone, it simply prints nothing rather than undefined as I was assuming if it did not exist...hmm
[18:44] <b41l3y> apparently it's and issue with the poster :D sorry about the false alarm!
[21:37] <oravecz> Since you guys have been discussing dispatcher configs, I thought I would mention ours. We replaced webapp.js with rest.js. It currently requires a configuration file that looks like this: http://gist.github.com/430699
[21:38] <oravecz> Of course a lot of that config can be made to work using convention, but it is still a work in progress for us.
[21:41] <hannesw> oravecz: how is profileId passed to the controller/action?
[21:41] <oravecz> re currently pass a second parameter to the controller which is a map of any properies parsed in from the url
[21:42] <oravecz> I've thought about just adding these to the req.params object instead
[21:42] <oravecz> or doing it the way the params are passed in webapp.js
[21:42] <oravecz> it also supports things like /profiles/:profileId/friends/:friendId
