I'm not sure if it fits this discussion, but I think automatic JSON
serialization is problematic since the serializer often has to guess
if a value needs to be serialized as a string or a number. This is not
a problem if you consume it with Perl or Javascript but it might be
problematic for some other languages (I have not seen it though).


On 12 August 2013 22:26, John Napiorkowski <jjn1...@yahoo.com> wrote:
>> On Monday, August 12, 2013 2:33 PM, Alexander Hartmaier 
>> <alexander.hartma...@t-systems.at> wrote:
>> > On 2013-08-12 16:58, John Napiorkowski wrote:
>>>  Hey Bill (and the rest of you lurkers!)
>>>  I just updated the spec over at
>> https://github.com/perl-catalyst/CatalystX-Proposals-REStandContentNegotiation/blob/master/README.pod
>>>  I decided to remove regular expression matching from the body parser stuff,
>> which I think resolves the merging questions (since now there will not be a
>> possibility that more that one can match the request).  I think we can add 
>> this
>> back eventually using some standard request content negotiation, using mime 
>> type
>> patterns and quality settings, so that we can have some rules that dictate 
>> what
>> is the best match, rather than try to invent our own.  For example:
>>>  https://metacpan.org/module/HTTP::Headers::ActionPack::ContentNegotiation
>>>  The idea would be to not reinvent.  I think we could instead of doing an
>> equality match here we just use something like this to figure out what the 
>> best
>> match is works pretty well.  Thoughts?
>>>  jnap
>> Hi John,
>> I thought about it for the last few days and wonder why the, lets call
>> it rendering, of the data isn't left to the view as defined by the MVC
>> pattern?
>> I'd expect that a different view is used depending on the negotiated
>> content-type.
>> How do other MVC frameworks choose the view to use?
>> Should a single action be able to limit the output format or is
>> controller level granular enough?
>> Best regards, Alex
> Alex,
> I think you put your finger on one of the major uneasiness I (and others) 
> have around the idea of having in the global application model all these 
> registered formatters.  Yes, in theory it feels like we are cheating on the 
> View side of MVC.  I have personally always thought that Catalyst doesn't 
> exactly get it right the way it is (I think C and V are actually a little too 
> detached for one thing) and that leads to odd code sometimes.  The commonly 
> used Catalyst::Action::Renderview is a bit too detached for my taste.  And 
> what we call a View tends to mostly just be a View handler (or factory I 
> guess).  On the other hand the basic idea of separation of concerns is sound.
> I think the main thing is that this is not intended to replace view, but for 
> the simple cases where people just want to quickly serialize data (like for 
> all those ajax endpoints you need to do nowadays, not full on RESTful APIs 
> but quick and dirty communication between the back and front end.  Maybe 
> that's not a great thing for Catalyst (and honestly I put this out there in 
> the hopes of provocation some strong reactions.
> Personally I prefer to use templates even for creating JSON output, I think 
> you get cleaner separation that is easier to maintain over time (I really 
> don't like when I see something like ->body (json_encode 
> $sql->run->get_all_rows).  That feels fragile to me.  On the other hand I see 
> the attraction of some of the more lightweight web frameworks where they make 
> it easy to just spew out JSON.
> This is partly why I sketched out an action/controller level alternative, 
> with the proposed response->body_format thing and the proposed new action 
> subroutine attributes  (just to recap)
> sub myaction :Local {
>   My ($self, $c) = @_;
>   # ...
>   # ...
>   $c->response->format(
>      'application/json' => sub {  json_encode $stuff },
>      # ...
>      # ...
>   );
> }
> I think this approach feels similar to how some other frameworks operate.  
> Some offer more sugary syntax for the common stuff, perhaps
> $c->response
>   ->json( sub { ... } )
>   ->html ( sub { ... } ).
>   -> ...
>   -> ... ;
> and I guess we could say there's a shortcut to forward to a View instead
> $c->response
>   ->json("JSON")
>   ->html ("TTHTML").
>   -> ...
>   -> ... ;
> But that can all be worked out after the basic thought is in place.
> and again, some other frameworks (some java system) they use annotations 
> similar to our action level subroutine attributes.  I think we also try to 
> hit that with the proposed "Provides/Consumes" attributes.  The main thing is 
> I can't see a way to properly do content negotiatin with ssubroutine 
> attributes given the exiting catalyst dispatcher (basically the system is 
> mostly a first match win)
> Perhaps that is all we need, and we can skip idea of needing default global 
> body formatters?  Or maybe we'd prefer to think about leveraging more of 
> Web::Dispatch, and mst has this great notion of setting response filters, 
> which we could get for free if we use web-dispatch.  Instead of setting a 
> global point for the encoding, we could control is more granularly that way.
> I guess ultimately it comes down to a question over do we need a full on view 
> for handling REST and straight up data encoding.  Personally I do think there 
> is a use case here that Catalyst isn't hitting right, and I am pretty sure 
> some of the ideas in the stand alone Catalyst-Action-REST do apply but I'd 
> like to see that more native and probably scoped more tightly (I don't think 
> we need or should have the full CAR in core, but I do think we should ask 
> ourselves.
> I guess its a bit tough to look at other frameworks since one thing about 
> Catalyst is that our idea of a Controller isn't so central as in other 
> frameworks, since with action chaining all the fun happens in the action 
> really.  ALthough chaining is powerful it does lead to some confusions in 
> terms of how to lay out the applications and so forth.
> I have some thoughts about that, but its really aimed at the future.
> I guess we could just drop the global format stuff, given the questions and 
> controversies.  I'd love to find a way that doesn't suck for people to be 
> able to do JSON response in Catalyst without a lot of boilerplate, but maybe 
> Catalyst isn't aimed to cater to that... The Catalyst::View::JSON is not too 
> bad, just has some docs that need updating I think.
> More thoughts and comments?
>>>>  On Friday, August 9, 2013 5:38 PM, John Napiorkowski
>> <jjn1...@yahoo.com> wrote:
>>>>  On Friday, August 9, 2013 4:52 PM, Bill Moseley
>> <mose...@hank.org> wrote:
>>>>>  On Fri, Aug 9, 2013 at 12:11 PM, John Napiorkowski
>> <jjn1...@yahoo.com>
>>>>  wrote:
>>>>  What's the use case you have in mind?  Something like first check
>> for
>>>>  something like 'application/vnd.mycompany.user+json' and then
>> fall back
>>>>  to 'application/(?:vmd.*+)?json' if you don't find it?  Is
>> that an
>>>>  actual case you've come across?
>>>>>  Ya, that's kind of what I was thinking.   Or also having a
>> final
>>>>  fallback parser that tries to figure out the type by other means than
>> just
>>>>  looking at the Content type provided in the request.  Or even a
>> '.'
>>>>  final match-anything that does some special logging.
>>>>>  It would be easy enough to find out if application/json was in the
>> array
>>>>  more than once by mistake.
>>>>  Seems like a reasonable use case then, although I would encourage
>> future
>>>>  development to aim at putting more specificity in the controller,
>> rather than
>>>>  rely on the global application.  The primary reason to have anything
>> here at all
>>>>  is to have a base people can build on.  I do fear the globalness of it,
>> but it
>>>>  seems not an unreasonable compromise based on how Catalyst actually
>> works today.
>>>>>>  We've spoken before about the parsing larger incoming and
>> chunked
>>>>  data thing before.  I would love to address this, but right now it
>> seems like
>>>>  something we need better agreement on in the psgi level.  For example,
>> since
>>>>  star man already buffers incoming input, it feels silly to me to have
>> catalyst
>>>>  then try to re-stream that.  You've already paid the full price of
>> buffering
>>>>  in terms of memory, and performance right?  Or am I not understanding?
>>>>>  I added a Plack middleware to handle chunked encoded requests -- I
>> needed it
>>>>  for the Catalyst dev server and for Apache/mod_perl.   Yes, Starman
>> already
>>>>  de-chunks and buffers and works perfectly.
>>>>>  Apache actually de-chunks the request, but doesn't update the
>>>>  Content-Length header and leaves on the Transfer-Encoding: chunked
>> header.  So,
>>>>  sadly, I do flush this to a temporary file only to get the
>> content-length to
>>>>  make Catalyst happy.
>>>>  Right, so I think in the end we all agreed it was psgi that should be
>>>>  responsible for dealing with chunks or whatever (based on the http
>> level support
>>>>  of the server).  The only think would be could there be some sane
>> approach that
>>>>  exposed the input stream as a non blockable file handle that has not
>> already
>>>>  been read into a buffer (memory or otherwise).  I do see the possible
>> advantage
>>>>  there for processing efficiently large POST or PUT.  However again this
>> needs to
>>>>  be done at the PSGI level, something like input.stream or similar.
>> That would
>>>>  smooth over chucked versus non chunked and expose a readable stream of
>> the input
>>>>  that has not yet been buffered.
>>>>>  I'd really like to have something at the Catalyst level that
>> sanely
>>>>  acheives this end, but I think part of the price we paid when going to
>> PSGi at
>>>>  the core, is that most of the popular plack handlers are pre loading
>> and
>>>>  buffering input, even large request input.  This seems to be an area
>> where it
>>>>  might behoove us to work with the psgi group to find something stable.
>> Even the
>>>>  optional psgix.io isn't always going to work out, since some people
>>>>  don't want to support that in the handler (its a somewhat vague
>> definition I
>>>>  guess and makes people uncomfortable).
>>>>>>  Until them, or until someone helps me understand that my
>> thinking is
>>>>  totally wrong on this score, it seems the best thing to do is to put
>> this out of
>>>>  scope for now.  That way we can move on supporting a goodly number of
>> real use
>>>>  cases.
>>>>>  Agreed.
>>>>>>  I intended to say that $_ equals a string that is the buffered
>> request
>>>>  body.  This way we can reserve other args for handling the future
>> streaming
>>>>  case.  I was actually pondering something were the sub ref returns a
>> sub ref
>>>>  that gets called over and over to do the parse.
>>>>>  I just don't want file uploads in memory.   (Oh, I have another
>> post
>>>>  coming on that -- thanks for the reminder.)
>>>>  Well, Catalyst doesn't but I think Starman might depending on the
>> size of
>>>>  the incoming.  However I think you can override that with a monkey
>> patch.
>>>>>   >
>>>>>>  I not quite sure about $c->res->body( \%data );   I
>> think body
>>>>  should be the raw body.   What does $c->res->body return?  The
>> serialized
>>>>  json?  The original hashref?
>>>>>>  I'm not sure I like it either.  I would say body returns
>> whatever
>>>>  you set it to, until the point were encoding happens.  It does feel a
>> bit flaky,
>>>>  but I can't actually put my finger on a real code smell here.
>>>>>>  Any other suggestions?  This is certainly a part of the
>> proposal that is
>>>>  going to raise doubt, but I can't think of something better, or
>> assemble
>>>>  problematic use cases in my head over it either.
>>>>>  I don't really mind adding to $c->stash->{rest}.
>> It's
>>>>  kind of a staging area to put data until it's ready to be encoded
>> into the
>>>>  body.   I might get it partially loaded with data and then never use it
>> and
>>>>  return some other body.   Noting precludes that, of course.   Ya, tough
>> one.
>>>>  Well, I definitely don't want to stick this in the stash, you all
>> will have
>>>>  to tie me down to get that past!  Given that body already allows a file
>> handle,
>>>>  I thought adding into that would be the most simple thing, but lets
>> give it more
>>>>  thought and maybe some other minds will come up with better ideas.
>> I'll
>>>>  bounce it off t0m and mst as well.
>>>>>>>  If a parser dies what kind of exception is thrown?   You
>> say they
>>>>  would not set any response status, but wouldn't we want to catch
>> the error
>>>>  and then set a 400?  (I use exception objects that carry http status, a
>> message
>>>>  to return in the body and a message used for logging at a given level.)
>>>>>>  How people do exceptions in Perl tends to be nearly religious,
>> and I
>>>>  didn't want to hold this up based on figuring that stuff out :)  I
>> was
>>>>  thinking to just raise an exception and let the existing Catalyst stuff
>> do its
>>>>  thing.  I'm just thinking not to add anything special for this type
>> of
>>>>  error, but just do the existing behavior, for better or worse.
>>>>>  Agreed.  If I were to write everything from scratch again I'd
>> be doing
>>>>  $c->throw_not_found or $c->throw_forbidden with exception objects
>> as the
>>>>  code ends up much cleaner and sane.   But, everyone has their own
>> approaches.
>>>>  One thing is to have the response->from_psgi thing which would make
>> ti easy
>>>>  to graft in something like https://metacpan.org/module/HTTP::Throwable
>>>>  sub myaction :Local {
>>>>  my ($self, $c) = @_;
>>>>  $c->res->from_psgi( http_throw({
>>>>      status_code => 500,
>>>>      reason      => 'Internal Server Error',
>>>>      message     => 'Something has gone very wrong!'
>>>>  }))
>>>>  }
>>>>  somthing along those lines I think.
>>>>>  since request->body_data is intended to be lazy, we won't
>> run that
>>>>  parse code until you ask for the data.  We don't need to parse the
>> data to
>>>>  do the basic match here, this is just based on the HTTP meta data, no
>> the actual
>>>>  content.  I think for common cases this is fine (I realize that yet
>> again this
>>>>  might not be the best approach for multipart uploads...)
>>>>>  Another tough one.    Just seems like PUT /user should accept the
>> same data
>>>>  regardless of how it is serialized.   And GET /user would get the user
>> data and
>>>>  then serialize that to JSON or whatever but it's the same data.
>>>>>  But, maybe you have a point.    I would worry that someone assumes
>> JSON and
>>>>  adds that content type match and then wonder why later it's not
>> working for
>>>>  other request serializations.
>>>>  well strikely speaking restful content negotiation should tell the
>> client what
>>>>  can and can't be accepted, for other purposes we have docs.  I
>> think its
>>>>  safe for the first go to just support json since for one of the main
>> use cases,
>>>>  making it easy for people building websites with some ajax forms, that
>> is all
>>>>  you need.  For more hard core REST I could easily see returning data
>> very
>>>>  differently based on what is asked.  Like an endoint could serve an
>> image if you
>>>>  ask for png, but metadata on the image if you ask for json.
>>>>>  --
>>>>>  Bill Moseley
>>>>>  mose...@hank.org
>>>>  _______________________________________________
>>>>  List: Catalyst@lists.scsys.co.uk
>>>>  Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
>>>>  Searchable archive:
>> http://www.mail-archive.com/catalyst@lists.scsys.co.uk/
>>>>  Dev site: http://dev.catalyst.perl.org/
>>>  _______________________________________________
>>>  List: Catalyst@lists.scsys.co.uk
>>>  Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
>>>  Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/
>>>  Dev site: http://dev.catalyst.perl.org/
>> *"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*
>> T-Systems Austria GesmbH Rennweg 97-99, 1030 Wien
>> Handelsgericht Wien, FN 79340b
>> *"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*
>> Notice: This e-mail contains information that is confidential and may be
>> privileged.
>> If you are not the intended recipient, please notify the sender and then
>> delete this e-mail immediately.
>> *"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*
>> _______________________________________________
>> List: Catalyst@lists.scsys.co.uk
>> Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
>> Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/
>> Dev site: http://dev.catalyst.perl.org/
> _______________________________________________
> List: Catalyst@lists.scsys.co.uk
> Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
> Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/
> Dev site: http://dev.catalyst.perl.org/

List: Catalyst@lists.scsys.co.uk
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/
Dev site: http://dev.catalyst.perl.org/

Reply via email to