getting the body of a POST

There is probably a very simple answer to this question but it is
stumping my weary brain.

I've got a service that is doing a POST to my ColdBox handler. It is
posting a very large JSON packet and due to things on their side, they
had to change the way it is being sent to me. Before it was a named
value, so I could just get the event request context, find the
variable and then parse it. No problem. But now the data is coming
through in the body of request, which means that it is no longer
named. How should I grab the contents of the body and how, if at all,
does it show up in the event request context?

Judah

See whatt the GetHttpRequestData() function gives you. If the data is
present in the results of that function, you could then add the needed
values to the request context yourself.

- Gabriel

Thanks Gabriel, that was what I was looking for. I had some other
confounding issues going on as well but the GetHttpRequestData()
function was what I really needed.

Question then for the list: Should data sent in the body of an http
request (POST or PUT) automatically make it into the Event Request
Collection the way that form field and url name/value parameters do? I
would say yes, it should. But you obviously can't attach a name to
that data in the request so CB would need a way to automatically
assign it a name in the request collection.

I'd suggest having a default variable name (like RequestBody) that
could be overridden in the CB config that is always present and gets
assigned the Content value of GetHttpRequestData() when it isn't
empty. Thoughts?

Judah

Hi Guys,

We will review GetHttpRequestData() adjustments, though you can
achieve this by having RequestContextDecorator.

I have already created a ticket for this enhancement.

Thanks
Sana

I think most people won't find much use for the content value. In
practice, I've only ever needed it when another entity (Google, etc)
is sending over data like in your case.

That said, we fortunately have the request context decorator like Sana
mentioned to add this type of functionality when desired.

- Gabriel

I agree. Thisbis a vey specific use case that the decorator covers easily.

There is one pretty significant use case (in my opinion) which is the
development of RESTful apps. In the case of POST and PUT verbs the
content will almost always be contained in the body. Given that
ColdBox has positioned itself as an ideal candidate for event-centric
apps and those are increasingly using REST-based design, it might be
wise to give it some consideration.

I'm fine adding it to a decorator for now but the idea of an MVC
pattern is to abstract out the location of the incoming data. You
don't have to check exactly where it came from, just that it exists in
the event request collection. One entirely reasonable place for that
data to be coming from is not currently being utilized.

Cheers,
Judah

The problem I see with automatically creating a variable in the rc for this is that it will do it ALL the time, and adding all name value pairs and just inflating the rc.

What about a utility method on the context to copy it explicitly so it can be used?
Or maybe getting it easily?

event.copyHTTPBody(“key name”);

or event.getHTTPBodyContent() that just retrieves the content?

Ideas?

1. That's my problem as well. If I submit a form with a post method,
the "content" field will not be blank and so automatically adding it
to the RC seems like unnecessary overhead. That said, the "content"
field is a legitimate source of input in cases like this.

I like "event.getHTTPBodyContent()" because I can explicitly call it
in the handler that is expecting input from the "content" and it
otherwise stays out of the way.

2. Or if you wanted to cover all bases, maybe something like:

a. event.getHTTPBodyContent() for cases where you're expecting the
input from that location
b. If your app communicates this way everywhere, then have a setting
(defaults to false) that would copy this information into the RC.

That way, if you need it a la carte, use the event function. If you
need it everywhere, set the setting to true and then a value would be
populated in the RC for you.

- Gabriel

I like this solution pretty well. It is true that some apps would use
it all the time and others would never use it. Mostly I just think
that the framework needs a documented way of getting at the content
and this accomplishes that goal. If I can dump the event object and
see that there is an easy way to get the http body content then that
should be good enough in my opinion.

Judah

Ok, here is another caveat for you:

What is so hard to do this in an event handler: getHTTPRequestData().content?? I am having a hard time justifying adding a method to the event context, when CF already does this for us??

+1

Agreed - keeping the CB core simple by usin ghe getHTTPRequestData().content and not replicating existing Coldfusion functionality without a solid reason appeals to me.

Tom

The big reason, in my opinion, is one of expectations. When I get data
posted to my handler, I expect to find it in RC. That is really rather
fundamental to MVC design pattern. In the case of data sent in the
body of the http request, that doesn't happen. If you know that it
isn't going to happen and you know how to get at the data and you know
that the data will be coming in via the body of the request then, yes,
it isn't that difficult to get at it.

Ideally, I'd like to see the data automatically show up in the RC just
like if you posted the data as a form field or via a GET. Barring
that, I like the idea of having a method that shows up when I dump
Event that has the method right there to get what I want. It isn't a
huge thing, true, it is just one of those niceties that CB does really
well where I don't have to go looking up the corresponding CF function
whose name I couldn't remember.

Anyway, not something that is a deal breaker in any way, I just think
that it would make it more obvious and easy for people using CB for
RESTful apps.

Cheers,
Judah

I don’t personally have a use case for it, but this seems like a great task for a RequestContextDecorator.