Tuesday, 23 April 2013

ColdFusion REST: is this a bug (in either CF or just my understanding)?

G'day:
(And, no, this is not a case of Betteridge's Law... I'm actually asking a question 'cos I don't know the answer).

I was having a mess around REST stuff this afternoon, half-heartedly trying to work out what the question actually was that someone asked on Twitter, and came across some puzzling behaviour. I don't really know REST from Adam (as it were) so this is definitely a question, not a statement.


Here's s repro case.

// Echo.cfc
component rest=true restPath="echo" {

    remote string function oneCorrectArg(required string arg1 restargsource="path") httpmethod="get" restpath="oneCorrectArg/{arg1}" {
        return serializeJson(arguments);
    }

    remote string function noRestArgSource(required string arg1) httpmethod="get" restpath="noRestArgSource/{arg1}" {
        return serializeJson(arguments);
    }

    remote string function mismatch(required string arg1 restargsource="path") httpmethod="get" restpath="mismatch/{wrongArg}" {
        return serializeJson(arguments);
    }

}

<!--- testEcho.cfm --->
<cfset argValue = createUuid()>
<cfoutput>#argValue#</cfoutput>
<hr>

<cfhttp method="get" url="http://localhost:8500/rest/components/echo/oneCorrectArg/#argValue#" result="oneCorrectArg" />
<cfdump var="#oneCorrectArg#">
<hr>

<cfhttp method="get" url="http://localhost:8500/rest/components/echo/noRestArgSource/#argValue#" result="noRestArgSource" />
<cfdump var="#noRestArgSource#">
<hr>

<cfhttp method="get" url="http://localhost:8500/rest/components/echo/mismatch/#argValue#" result="mismatch" />
<cfdump var="#mismatch#">

The output for this is:

160B2283-215D-AD32-CE4BC77B7321BECC

struct
Charset[empty string]
ErrorDetail[empty string]
Filecontent{"ARG1":"160B2283-215D-AD32-CE4BC77B7321BECC"}
HeaderHTTP/1.1 200 OK Server: Apache-Coyote/1.1 Content-Type: text/plain Transfer-Encoding: chunked Date: Tue, 23 Apr 2013 05:39:36 GMT Connection: close
Mimetypetext/plain
Responseheader
Statuscode200 OK
TextYES

struct
Charset[empty string]
ErrorDetail[empty string]
Filecontent{"ARG1":""}
HeaderHTTP/1.1 200 OK Server: Apache-Coyote/1.1 Content-Type: text/plain Transfer-Encoding: chunked Date: Tue, 23 Apr 2013 05:39:36 GMT Connection: close
Mimetypetext/plain
Responseheader
Statuscode200 OK
TextYES

struct
Charset[empty string]
ErrorDetail[empty string]
Filecontent{"Message":"The ARG1 parameter to the mismatch function is required but was not passed in."}
HeaderHTTP/1.1 500 Internal Server Error Server: Apache-Coyote/1.1 Content-Type: text/plain Content-Length: 92 Date: Tue, 23 Apr 2013 05:39:36 GMT Connection: close
Mimetypetext/plain
Responseheader
Statuscode500 Internal Server Error
TextYES

The green one and the red one are fine. But what's up with the orange one? Here's the method again:

remote string function noRestArgSource(required string arg1) httpmethod="get" restpath="noRestArgSource/{arg1}" {
    return serializeJson(arguments);
}

I require an argument arg1, and I set the restpath, but I don't correlate the restpath back to the argument with a restArgSource attribute on the argument. Compare with the working method:

remote string function oneCorrectArg(required string arg1 restargsource="path") httpmethod="get" restpath="oneCorrectArg/{arg1}" {
    return serializeJson(arguments);
}

Within the method arg1 is defined and has an empty value. Which is, no matter how one spins it, not correct. What I'd expect here is to get an exception along the lines of the mismatch() method, because noRestArgSource() actually shouldn't be getting passed an arg1 value, yet it requires one.

Obviously my code is bung here, but he bungness doesn't seem to be getting handled correctly here.

Am I not understanding something, or is this a wee bug? Cheers for any insight anyone can offer.

--
Adam