[Catalyst] More detailed proposal for changes related to content
negotiation and REST
Bill Moseley
moseley at hank.org
Fri Aug 9 20:51:49 GMT 2013
On Fri, Aug 9, 2013 at 12:11 PM, John Napiorkowski <jjn1056 at 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 ca=
se
> 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.
>
> 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 ha=
ve
> 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.
> 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 PS=
Gi
> at the core, is that most of the popular plack handlers are pre loading a=
nd
> 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 streami=
ng
> 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.)
>
> >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.
>
> >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 messa=
ge
> 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.
> 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 t=
he
> 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.
-- =
Bill Moseley
moseley at hank.org
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.scsys.co.uk/pipermail/catalyst/attachments/20130809/ae2f7=
fa2/attachment.htm
More information about the Catalyst
mailing list