[cgiapp] Best practice for CGI errors

2008-09-22 Thread Mark Knoop

Hi

I suspect the reason I can't fun the answer for this is that it is too 
obvious... but I am having a moment of doubt!


If one wants to return an error to the client because they have not included 
the correct parameters for the CGI request, should one use one of the HTTP 
status codes and if so which one? And then is it ok/sensible to include an 
error message in the body?


Or should success or failure at the app level be indicated solely in the 
body of the response, with the HTTP response codes only being used to 
indicate an HTTP error ie if they don't include the correct parameters for 
one's app but it is still a valid HTTP request then use 200 but have some 
error notification inside the response body. If this is the case is there 
any kind of standard practice?


I should probably mention that I am not responding with HTML here but rather 
this is a simple API or 'web service' - however I was hoping to avoid using 
SOAP or the like as it is very simple and CGI style GET with the return 
value in the response body should work fine - just having a momentary 
quandary on the error issue.


Any suggestions gratefully receieved!

Cheers
Mark 



#  CGI::Application community mailing list  
####
##  To unsubscribe, or change your message delivery options,  ##
##  visit:  http://www.erlbaum.net/mailman/listinfo/cgiapp##
####
##  Web archive:   http://www.erlbaum.net/pipermail/cgiapp/   ##
##  Wiki:  http://cgiapp.erlbaum.net/ ##
####




Re: [cgiapp] Best practice for CGI errors

2008-09-22 Thread Michael Peters

Mark Knoop wrote:

If one wants to return an error to the client because they have not 
included the correct parameters for the CGI request, should one use one 
of the HTTP status codes and if so which one? 


Generally I don't use the HTTP status codes unless there is an error on the HTTP level. So for HTTP 
redirection, general server problem, etc. But HTTP codes are not application specific codes.


And then is it ok/sensible 
to include an error message in the body?


For me application specific codes should be part of the application, so it's part of the response. 
Are you returning your response as structured data (XML, JSON, etc)? If so, I'd just define a part 
of the spec that lists your application specific error codes and what they mean. If your response is 
not structured data, then just put a human readable error in the response.


--
Michael Peters
Plus Three, LP


#  CGI::Application community mailing list  
####
##  To unsubscribe, or change your message delivery options,  ##
##  visit:  http://www.erlbaum.net/mailman/listinfo/cgiapp##
####
##  Web archive:   http://www.erlbaum.net/pipermail/cgiapp/   ##
##  Wiki:  http://cgiapp.erlbaum.net/ ##
####




Re: [cgiapp] Best practice for CGI errors

2008-09-22 Thread Mark Knoop



Mark Knoop wrote:

If one wants to return an error to the client because they have not 
included the correct parameters for the CGI request, should one use one 
of the HTTP status codes and if so which one?


Generally I don't use the HTTP status codes unless there is an error on 
the HTTP level. So for HTTP redirection, general server problem, etc. But 
HTTP codes are not application specific codes.



And then is it ok/sensible to include an error message in the body?


For me application specific codes should be part of the application, so 
it's part of the response. Are you returning your response as structured 
data (XML, JSON, etc)? If so, I'd just define a part of the spec that 
lists your application specific error codes and what they mean. If your 
response is not structured data, then just put a human readable error in 
the response.


--
Michael Peters
Plus Three, LP



Thanks Michael.

I was going to have a single line of text in the response containing the 
method return value which was why I was wondering if there was another way 
of indicating an error (in which case I would use the response body for an 
error message).


Of course it would be easy to include more info in the response - but then 
perhaps I should reconsider my approach re how to implement an RPC 
so


...while I am here (and acknowledging that this is slightly off topic but at 
the same time it is probably somehting that many of you have had much 
experience in 'real-world' scenarios) can I ask whether CGI::App users have 
any favourite ways to do it re 'web services' ie remote methods/apis that do 
something then return some data? SOAP, XML-RPC, bespoke XML/JSON/other in 
response to GET/POST with CGI params, any other approach? My methods and 
responses are very simple. It would be nice to have hassle free security 
already there - this was the one advantage to SOAP - the main disadvantage 
being a lack of understanding on my part...


Cheers
Mark



#  CGI::Application community mailing list  
####
##  To unsubscribe, or change your message delivery options,  ##
##  visit:  http://www.erlbaum.net/mailman/listinfo/cgiapp##
####
##  Web archive:   http://www.erlbaum.net/pipermail/cgiapp/   ##
##  Wiki:  http://cgiapp.erlbaum.net/ ##
####




Re: [cgiapp] Best practice for CGI errors

2008-09-22 Thread Michael Peters

Mark Knoop wrote:

...while I am here (and acknowledging that this is slightly off topic 
but at the same time it is probably somehting that many of you have had 
much experience in 'real-world' scenarios) can I ask whether CGI::App 
users have any favourite ways to do it re 'web services' ie remote 
methods/apis that do something then return some data? SOAP, XML-RPC, 
bespoke XML/JSON/other in response to GET/POST with CGI params, any 
other approach? My methods and responses are very simple. 


For simplicity (speed, human readability, etc) you can't beat JSON. I love it. And if you allow some 
JSONP you can make it easy for people to use your service to build mashups. You can have your 
clients make submissions that are simple requests with a JSON document as part of the request or you 
can use normal CGI style parameters. Really up to you.


I'd avoid SOAP if I were you. It's overly complex and there are a lots of different variations. 
Compatibility between systems is not given and can be a real big headache.


It would be 
nice to have hassle free security already there - this was the one 
advantage to SOAP - the main disadvantage being a lack of understanding 
on my part...


I could be completely wrong, but I don't see how SOAP provide security to your application? You 
still need to implement whatever security scheme you decide on and you can always use SOAP's basic 
security model for your own application if you want. But as far as security in web services goes 
I've had good success with the following:


1) username and passwords. Treat it just like other web stuff. The only difference is that you don't 
really use a cookie, you just make them send the username and password on every request.


2) crytographic token. Very similar to #1 but instead of passing a username and pw with each request 
it's just a simple token. You'd give each client a separate token which you can then verify on each 
request. You can also embed data into the token itself like client id, etc. You can even embed 
something like the origin IP address in there so that client can't give your tokens away to other 
people.


--
Michael Peters
Plus Three, LP


#  CGI::Application community mailing list  
####
##  To unsubscribe, or change your message delivery options,  ##
##  visit:  http://www.erlbaum.net/mailman/listinfo/cgiapp##
####
##  Web archive:   http://www.erlbaum.net/pipermail/cgiapp/   ##
##  Wiki:  http://cgiapp.erlbaum.net/ ##
####




[cgiapp] Re: New plugin idea based/inspired on CA Dispatch.

2008-09-22 Thread Mark Stosberg
 I already started writing a CA plugin and I'd love to hear what you all think
 (if the idea/plugin can be useful or just a waste of time).  I have my own
 thoughts but I can be missing something and I'd like to have other opinions.
 Based and inspired in CA Dispatch, also borrowing some code, the plugin
 should work as a *light* implementation from CA Dispatch for simple CA based
 apps.
 
 In my daily work, I usually write simple CA apps, always with a couple of
 runmodes (usually, around 8) and a single application module (no need to have
 more, since the apps usually are fairly simple). Also, I usually need to
 implement clean url's.
 
 In this context, what I did so far is to adapt the url parsing routine from
 CA Dispatch (receiving from the CA app a dispatch table in the same way CA
 Dispatch does) and *adding* the parsed params/values into CGI.pm params, in a
 way they can be retrieved in the CA based app with the usual
 $app-query-param('parsed_param_name'); method.
 
 Since this is my first plugin AND I never been in touch with CA other than
 doing my simple CA apps, I dont know if this idea is good, ok, heresy or just
 stupid.

Porta,

I think is a great idea. I really like it. I could also see it being used along
with ::Dispatch: -- The global dispatcher might handle passing the flow into
the right module, and then this plugin would pick up from there.

While a global dispatcher is nice, sometimes it's more helpful to keep the the
related dispatch table and run modes closer together. 

In my workflow, I found a global Dispatch.pm to be a point of conflict, in the
source control sense: Two unrelated projects may both modify a global
Dispatch.pm. When I go to launch one project, the other project becomes a
dependency. (I solved that by recording changes to Dispatch.pm separately from
other work).

I have some specific suggestions on your implementation:

- rename routes_table to just routes. I don't think the word table adds 
much.

- Consider having routes_table() automatically add every run mode dispatched 
to
  the run_modes hash, if a subroutine with that name exists in the current
  scope. (I suppose you can use the can() method to test for that? ).

  That will eliminate the need to make a separate call to run_modes() in most
  cases, unless you have a run mode that points to a code-ref that you need to
  call.

Mark

-- 
 . . . . . . . . . . . . . . . . . . . . . . . . . . . 
   Mark StosbergPrincipal Developer  
   [EMAIL PROTECTED] Summersault, LLC 
   765-939-9301 ext 202 database driven websites
 . . . . . http://www.summersault.com/ . . . . . . . .



#  CGI::Application community mailing list  
####
##  To unsubscribe, or change your message delivery options,  ##
##  visit:  http://www.erlbaum.net/mailman/listinfo/cgiapp##
####
##  Web archive:   http://www.erlbaum.net/pipermail/cgiapp/   ##
##  Wiki:  http://cgiapp.erlbaum.net/ ##
####




[cgiapp] Re: New plugin idea based/inspired on CA Dispatch.

2008-09-22 Thread Mark Stosberg
On Mon, 22 Sep 2008 11:36:24 -0400
Mark Stosberg [EMAIL PROTECTED] wrote:

  I already started writing a CA plugin and I'd love to hear what you all 
  think
  (if the idea/plugin can be useful or just a waste of time).  I have my own
  thoughts but I can be missing something and I'd like to have other opinions.
  Based and inspired in CA Dispatch, also borrowing some code, the plugin
  should work as a *light* implementation from CA Dispatch for simple CA based
  apps.
  
  In my daily work, I usually write simple CA apps, always with a couple of
  runmodes (usually, around 8) and a single application module (no need to 
  have
  more, since the apps usually are fairly simple). Also, I usually need to
  implement clean url's.
  
  In this context, what I did so far is to adapt the url parsing routine from
  CA Dispatch (receiving from the CA app a dispatch table in the same way CA
  Dispatch does) and *adding* the parsed params/values into CGI.pm params, in 
  a
  way they can be retrieved in the CA based app with the usual
  $app-query-param('parsed_param_name'); method.
  
  Since this is my first plugin AND I never been in touch with CA other than
  doing my simple CA apps, I dont know if this idea is good, ok, heresy or 
  just
  stupid.
 
 Porta,
 
 I think is a great idea. I really like it. I could also see it being used 
 along
 with ::Dispatch: -- The global dispatcher might handle passing the flow into
 the right module, and then this plugin would pick up from there.
 
 While a global dispatcher is nice, sometimes it's more helpful to keep the the
 related dispatch table and run modes closer together. 
 
 In my workflow, I found a global Dispatch.pm to be a point of conflict, in the
 source control sense: Two unrelated projects may both modify a global
 Dispatch.pm. When I go to launch one project, the other project becomes a
 dependency. (I solved that by recording changes to Dispatch.pm separately from
 other work).
 
 I have some specific suggestions on your implementation:
 
 - rename routes_table to just routes. I don't think the word table adds 
 much.
 
 - Consider having routes_table() automatically add every run mode 
 dispatched to
   the run_modes hash, if a subroutine with that name exists in the current
   scope. (I suppose you can use the can() method to test for that? ).
 
   That will eliminate the need to make a separate call to run_modes() in 
 most
   cases, unless you have a run mode that points to a code-ref that you need to
   call.

One more suggestion: 

Break out all the code in the 'for' loop that processes a single route into
it's own subroutine.  That would allow someone to 'use' this plugin and build
on it to parse the 'route' out of a subroutine attribute, like Catalyst does.

And perhaps one more suggestion:
Perhaps there should be an option to set a path for which all the routes are
relative to. For example:

 $c-routes_root('/app/volunteer/profile');

And then in the routing table, or in a potential signature, you can be relative 
to that:

$c-route(
# maps to /app/volunteer/profile/edit/:id
'edit/:id'  = 'edit'
);

# Or
 sub edit ('/edit/:id') {
 }


Now, when I saw Matt Trout, a Catalyst maintainer at YAPC, he was having second
thoughts about using subroutine attributes in Catalyst, although he didn't go
into detail. And I have run into problems with them in the past.

So, I'm not recommending that style as being preferred, but I think it's an
option some people might enjoy having.

Mark



#  CGI::Application community mailing list  
####
##  To unsubscribe, or change your message delivery options,  ##
##  visit:  http://www.erlbaum.net/mailman/listinfo/cgiapp##
####
##  Web archive:   http://www.erlbaum.net/pipermail/cgiapp/   ##
##  Wiki:  http://cgiapp.erlbaum.net/ ##
####




Re: [cgiapp] Best practice for CGI errors

2008-09-22 Thread Mark Knoop



Mark Knoop wrote:

...while I am here (and acknowledging that this is slightly off topic but 
at the same time it is probably somehting that many of you have had much 
experience in 'real-world' scenarios) can I ask whether CGI::App users 
have any favourite ways to do it re 'web services' ie remote methods/apis 
that do something then return some data? SOAP, XML-RPC, bespoke 
XML/JSON/other in response to GET/POST with CGI params, any other 
approach? My methods and responses are very simple.


For simplicity (speed, human readability, etc) you can't beat JSON. I love 
it. And if you allow some JSONP you can make it easy for people to use 
your service to build mashups. You can have your clients make submissions 
that are simple requests with a JSON document as part of the request or 
you can use normal CGI style parameters. Really up to you.


I'd avoid SOAP if I were you. It's overly complex and there are a lots of 
different variations. Compatibility between systems is not given and can 
be a real big headache.


It would be nice to have hassle free security already there - this was 
the one advantage to SOAP - the main disadvantage being a lack of 
understanding on my part...


I could be completely wrong, but I don't see how SOAP provide security to 
your application? You still need to implement whatever security scheme you 
decide on and you can always use SOAP's basic security model for your own 
application if you want. But as far as security in web services goes I've 
had good success with the following:


1) username and passwords. Treat it just like other web stuff. The only 
difference is that you don't really use a cookie, you just make them send 
the username and password on every request.


2) crytographic token. Very similar to #1 but instead of passing a 
username and pw with each request it's just a simple token. You'd give 
each client a separate token which you can then verify on each request. 
You can also embed data into the token itself like client id, etc. You can 
even embed something like the origin IP address in there so that client 
can't give your tokens away to other people.


--
Michael Peters
Plus Three, LP




Thanks for this. I like the look of JSON(P)... will investigate further as 
an alternative to XML. Re SOAP security it was just that I had working 
examples of clients accessing a proxy via ssl but I guess that there is no 
reason why I cannot use https with a normal CGI request - I just never have 
done (or at least not with a dynamic client as opposed to a browser). 
Username and password just get passed as normal parameters so as long as 
they are ssl'd that's fine.


Best, Mark 



#  CGI::Application community mailing list  
####
##  To unsubscribe, or change your message delivery options,  ##
##  visit:  http://www.erlbaum.net/mailman/listinfo/cgiapp##
####
##  Web archive:   http://www.erlbaum.net/pipermail/cgiapp/   ##
##  Wiki:  http://cgiapp.erlbaum.net/ ##
####




[cgiapp] Re: New plugin idea based/inspired on CA Dispatch.

2008-09-22 Thread Mark Stosberg

 Now, when I saw Matt Trout, a Catalyst maintainer at YAPC, he was having 
 second
 thoughts about using subroutine attributes in Catalyst, although he didn't go
 into detail. And I have run into problems with them in the past.
 
 So, I'm not recommending that style as being preferred, but I think it's an
 option some people might enjoy having.

Here's a current conversation about the past and future of subroutine attributes
in Catalyst:

http://use.perl.org/comments.pl?sid=41074cid=65070

It does sound questionable that using them as a core framework feature giving
the state of what's possible (and works well) with Perl now.

Mark



#  CGI::Application community mailing list  
####
##  To unsubscribe, or change your message delivery options,  ##
##  visit:  http://www.erlbaum.net/mailman/listinfo/cgiapp##
####
##  Web archive:   http://www.erlbaum.net/pipermail/cgiapp/   ##
##  Wiki:  http://cgiapp.erlbaum.net/ ##
####




Re: [cgiapp] Best practice for CGI errors

2008-09-22 Thread Jaldhar H. Vyas

On Mon, 22 Sep 2008, Mark Knoop wrote:

If one wants to return an error to the client because they have not included 
the correct parameters for the CGI request, should one use one of the HTTP 
status codes and if so which one? And then is it ok/sensible to include an 
error message in the body?




If you've drunk the REST koolaid (or like me drained the entire pitcher :-) ) 
you should always be thinking of leveraging HTTP features as much as 
possible and that would mean using status codes.  I would suggest 400 
('Bad request')


An error message in the body is good for providing additional info to 
humans but the API of your web service should not depend on it in any way.



--
Jaldhar H. Vyas [EMAIL PROTECTED]

#  CGI::Application community mailing list  
####
##  To unsubscribe, or change your message delivery options,  ##
##  visit:  http://www.erlbaum.net/mailman/listinfo/cgiapp##
####
##  Web archive:   http://www.erlbaum.net/pipermail/cgiapp/   ##
##  Wiki:  http://cgiapp.erlbaum.net/ ##
####




[cgiapp] Re: New plugin idea based/inspired on CA Dispatch.

2008-09-22 Thread Porta
Mark.
Thanks for your feedback.
I already did the change you suggested to change routes_table to
routes. But I must to admit that is not clear to me what you mean
with this one.

- Consider having routes_table() automatically add every run mode
dispatched to
 the run_modes hash, if a subroutine with that name exists in the current
 scope. (I suppose you can use the can() method to test for that? ).

Maybe because I'm not pro-efficient with perl enough, or maybe I'm
missing something?

Also,. I liked this:

Perhaps there should be an option to set a path for which all the routes are
relative to. For example:

 $c-routes_root('/app/volunteer/profile');

I definitely going to include that change.

But, about the catalyst style, I didn't liked the approach, and, also,
see something (I think almost) exactly like that in
CAP::Actiondispatch
(http://search.cpan.org/~jaywhy/CGI-Application-Plugin-ActionDispatch-0.96/lib/CGI/Application/Plugin/ActionDispatch.pm)
and I really didn't liked it (or just didn't worked for me).

Thanks.

Julián Porta.

#  CGI::Application community mailing list  
####
##  To unsubscribe, or change your message delivery options,  ##
##  visit:  http://www.erlbaum.net/mailman/listinfo/cgiapp##
####
##  Web archive:   http://www.erlbaum.net/pipermail/cgiapp/   ##
##  Wiki:  http://cgiapp.erlbaum.net/ ##
####




[cgiapp] Patches available for ::Plugin::Routes (was: Re: New plugin idea based/inspired on CA Dispatch)

2008-09-22 Thread Mark Stosberg

 I already did the change you suggested to change routes_table to
 routes. 

Great. 

 with this one.
 
 - Consider having routes_table() automatically add every run mode
 dispatched to
  the run_modes hash, if a subroutine with that name exists in the current
  scope. (I suppose you can use the can() method to test for that? ).
 
 Maybe because I'm not pro-efficient with perl enough, or maybe I'm
 missing something?

I've sent you patches via github that implement this for you now. You
can browse them here:

http://github.com/markstos/cgi--application--plugin--routes/commits/master

When registering routes, we also try to automatically register the run
mode names. We will register a run mode when there is not already one
defined with the target name and we 'can' call a method with the same
name.

This means that for you common cases when you call 'routes', you can
skip calling run_modes().

My other patches improved your 'import' routine, created proper
automated tests, and made sure Data::Dumper was only loaded if it was
required.

 Also,. I liked this:
 
 Perhaps there should be an option to set a path for which all the routes are
 relative to. For example:
 
  $c-routes_root('/app/volunteer/profile');
 
 I definitely going to include that change.

Great!

 But, about the catalyst style, I didn't liked the approach, and, also,
 see something (I think almost) exactly like that in
 CAP::Actiondispatch
 (http://search.cpan.org/~jaywhy/CGI-Application-Plugin-ActionDispatch-0.96/lib/CGI/Application/Plugin/ActionDispatch.pm)
 and I really didn't liked it (or just didn't worked for me).

I had forgetten about that. I never used it myself. I think I prefer the
approach in this new plugin. 

A bit of further feedback: 

- Your POD coverage test is still failing. 

Mark

-- 
http://mark.stosberg.com/




#  CGI::Application community mailing list  
####
##  To unsubscribe, or change your message delivery options,  ##
##  visit:  http://www.erlbaum.net/mailman/listinfo/cgiapp##
####
##  Web archive:   http://www.erlbaum.net/pipermail/cgiapp/   ##
##  Wiki:  http://cgiapp.erlbaum.net/ ##
####




[cgiapp] RE: Patches available for ::Plugin::Routes (was: Re: New plugin idea based/inspired on CA Dispatch)

2008-09-22 Thread Porta
Wonderful changes.
I'll review the POD problem. First time with it.

Thanks.

Julián.


 I already did the change you suggested to change routes_table to
 routes.

Great.

 with this one.

 - Consider having routes_table() automatically add every run mode
 dispatched to
  the run_modes hash, if a subroutine with that name exists in the current
  scope. (I suppose you can use the can() method to test for that? ).

 Maybe because I'm not pro-efficient with perl enough, or maybe I'm
 missing something?

I've sent you patches via github that implement this for you now. You
can browse them here:

http://github.com/markstos/cgi--application--plugin--routes/commits/master

When registering routes, we also try to automatically register the run
mode names. We will register a run mode when there is not already one
defined with the target name and we 'can' call a method with the same
name.

This means that for you common cases when you call 'routes', you can
skip calling run_modes().

My other patches improved your 'import' routine, created proper
automated tests, and made sure Data::Dumper was only loaded if it was
required.

 Also,. I liked this:

 Perhaps there should be an option to set a path for which all the routes are
 relative to. For example:

  $c-routes_root('/app/volunteer/profile');

 I definitely going to include that change.

Great!

 But, about the catalyst style, I didn't liked the approach, and, also,
 see something (I think almost) exactly like that in
 CAP::Actiondispatch
 (http://search.cpan.org/~jaywhy/CGI-Application-Plugin-ActionDispatch-0.96/lib/CGI/Application/Plugin/ActionDispatch.pm)
 and I really didn't liked it (or just didn't worked for me).

I had forgetten about that. I never used it myself. I think I prefer the
approach in this new plugin.

A bit of further feedback:

- Your POD coverage test is still failing.

Mark

-- 
http://mark.stosberg.com/

#  CGI::Application community mailing list  
####
##  To unsubscribe, or change your message delivery options,  ##
##  visit:  http://www.erlbaum.net/mailman/listinfo/cgiapp##
####
##  Web archive:   http://www.erlbaum.net/pipermail/cgiapp/   ##
##  Wiki:  http://cgiapp.erlbaum.net/ ##
####