I am working on finishing the REST interfaces for a new application, and I am trying to use the PUT verb to save some resources. When I use PUT, I notice that the data I pass to the server comes through as the HTTP request content, which I can retrieve like so:
GetHttpRequestData().content
I am wondering if there is a better or pre-configured way of accessing this data in Coldbox by dafault, or if I should just use this method. The data passed does not show up in the request collection, so I assume it is not getting parsed by Coldbox by default.
Note that I am using the Coldbox SES method in request handlers to build my REST interfaces, I am not using CF/Railo REST capabilities at this time.
Thanks,
Robert
When I said request handler, I meant Event Handler…
In 3.5.3, at least, I don’t think there is a built in facility in ColdBox to add PUT content into the RC, for example. If you look at the code that creates RC, it’s basically smashing together FORM and URL…and of course, on a PUT, the request data isn’t in either of those. https://github.com/ColdBox/coldbox-platform/blob/bb08f37ed37bf15058be3066d9e4192455c9975a/system/web/services/RequestService.cfc (requestCapture)
For my app, we have created an interceptor that keys on the onRequestCapture() interception point. In this method, it checks the HTTP verb, and if it’s a PUT request, it parses the content retrieved from event.getHTTPContent() and adds it to the RC. This allows us to treat it just as if it had come through the form, so the handler doesn’t have to care about it whatsoever.
Hope that helps!
Ah, exactly what I was looking for, thanks Joel. I was about to do something similar.
I would vote for that as a future enhancement to the core Coldbox REST system.
Sure, glad it was helpful!
Care to submit a ticket? https://ortussolutions.atlassian.net
Joel,
Do you also POST the data the same way, or does it come through in the FORM (rc)? I suppose it depends on the REST service you are using… it appears that Angular’s ngResource is also setting this content to the request body as well. Is there any reason why I should request to use the RC vs parsing out the body content?
I’m thinking about this too, building a REST back end for a Vue.js app, where all client requests have the content in the request body.
Unless I’m missing some relevant configuration option, the CB REST template still has each handler doing something like this in every REST-accessible method:
data = deserializeJSON(toString(getHTTPRequestData().content))
I’m surprised, since in general ColdBox is all about teaching the infrastructure about patterns like this. I’d expect something more like one this in /coldbox/system/web/services/RequestService.cfc.requestCapture():
- Always check for a json request body if FORM and URL are empty (first 2 lines are the existing code):
if( isDefined( “FORM” ) ){ structAppend( rc, FORM ); }
if( isDefined( “URL” ) ){ structAppend( rc, URL ); }
if (structIsEmpty(rc))
{
requestBody = toString(getHTTPRequestData().content);
if (isJSON(requestBody))
structAppend(rc, deserializeJSON(requestBody));
}
- Have an overridable detection method that examines some piece of request metadata to see if that’s expected, for instance if Content-Type is application/json. If the client flags content in the request body differently, you’d override that method appropriately.
Am I missing how we’re expected to implement such things, or some great reason why there’s nothing built in out of the box? Could well be, I’m very new to ColdBox. Should I submit a PR with strategy #1?
Thanks,
Dave
BTW, I don’t see why some strategy like that should be confined to PUT requests. My app needs this on some GETs too.
Dave
And though I didn’t want to change the subject line, I’m asking about the current release, 4.3 as I write this.
Dave