Consumer code?

4 views
Skip to first unread message

Brian G

unread,
Jan 12, 2009, 3:08:09 PM1/12/09
to cfrest

The project I'm working on currently is to extract the payment
processing system in my e-commerce application to a remote server that
is stored in a PCI DSS compliant environment. By not running the
cards through our network, we'll be able to greatly reduce the scope
of our compliance. The user flow looks something like:

User fills form on www that posts to proxy and clicks submit, proxy
processes payment and redirects back to www for result display

In the middle step, the background flow on the proxy server looks
like:

Proxy receives payment request, calls REST api to add payment (or gets
403 saying payment already exists which is used to stop a double-
charge), processes payment using CFPAYMENT, calls REST api to update
payment with results, redirects back to www.

This is a transparent redirect; the user will never see any output
from the proxy unless there is a fatal explosion. On a side note,
I've switched my custom REST code over to Brian's PowerNAP which was
pretty painless and is working well. It'll be easy to add new
resources now.

As part of this project, I now need to consume my REST API... for the
proxy server to query and add records to the database for payment
attempts and success/failures. I was wondering if anyone had any
recommendations for consuming? Or perhaps there exists somewhere a
generic REST consumer CFC?

I could go through the workflow diagram on restpatterns and account
for every possible scenario but I figured you two might have some
better ideas. :)


Brian

websolete

unread,
Jan 13, 2009, 1:32:32 AM1/13/09
to cfrest
Brian,

What are you after exactly? To CFHTTP or not to CFHTTP? Or just a
standardized way of making calls?

In my REST-api consuming app I have an app-scoped singleton which has
methods for the various http calls (GET, POST, etc.) and all calls to
external apis must go through them, so the argument structure and
response handling at least is consistent. Additionally, there are
methods related to transforming the response from XML/JSON/etc.to cf
objects, and from cf to XML/JSON/etc. for POST/PUT/DELETE, which are
called pre- and post- api consuming methods.

Do we/can we create a code pool here? Perhaps if I were to paste cfc
code here that I currently use to for the process you describe that
would help shape the direction you'd like to go; always easier to edit
or change something existing than to start from scratch, or at least
you can say 'that sucks' and still have narrowed down your approach a
bit by removing one option.

If I have a handful of cfc's that are relevant, do I upload them as
files or paste code into replies? Sorry, I'm a GG noob.

Kevin

Brian G

unread,
Jan 13, 2009, 9:57:02 PM1/13/09
to cfrest

On Jan 12, 10:32 pm, websolete <websol...@gmail.com> wrote:
> What are you after exactly?  To CFHTTP or not to CFHTTP?  Or just a
> standardized way of making calls?

Some helper functions is probably the short of it. I came up with a
RestConsumer.cfc that has create(), update(), delete(), get() and a
centralized CFHTTP wrapper... it's working so far ok except I can't
figure out how to pass parameters with a PUT request?

Like say I have foo = a, bar = 1 and snafu = twenty. How would I pass
those three parameters and their values with a CFHTTP PUT request?
I've tried formfields and cgi but those don't work and you can only
have a single cfhttpparam type="Body" per request. I feel like I'm
missing something obvious?

> Do we/can we create a code pool here?  Perhaps if I were to paste cfc
> code here that I currently use to for the process you describe that
> would help shape the direction you'd like to go; always easier to edit
> or change something existing than to start from scratch, or at least

That would be awesome - good for the wiki you're setting up but in the
mean time you can upload files to the Google group I believe. If you
can't do it, you can email them to me and I'll post them. I'm not
sure if there are permissions and stuff on here.


Brian

websolete

unread,
Jan 14, 2009, 2:15:32 AM1/14/09
to cfrest
Brian,

I uploaded apiUtilities.cfc to the files section. This is most likely
the equivalent of your RestConsumer.cfc.

Note that a PUT is for most intents and purposes functionally
equivalent to POST, at least in the manner of 'posting' request bodies
of xml or json encoded content. To that end, you'll see that both the
PUT and POST take a requestbody argument which is the xml or json
packet containing all the values. There are no other formfields to
speak of, and any auth is either contained in the packet itself, via
http auth in cfhttp, or as header params in the request itself. I've
also uploaded a simple response/request packet example which shows the
format of a request packet as it is in my api.

I believe that if you need to include 'form field' values which are
not explicitly defined as being required to be part of the request
body, and therefore implicitly beyond the scope of the target api,
that they should be sent as URL params and be part of the resource
URI, but thats of course up to the target api to define.

The only thing to be done is the prep of the packet (body) contents
prior to PUTting or POSTting.

Kevin

Brian G

unread,
Jan 14, 2009, 7:05:27 PM1/14/09
to cfrest

On Jan 13, 11:15 pm, websolete <websol...@gmail.com> wrote:
> I uploaded apiUtilities.cfc to the files section.  This is most likely
> the equivalent of your RestConsumer.cfc.

Thanks! I've taken a look (and emailed you offline about the PUT/
binary issue) and it helped me finalize the restconsumer.cfc I
started. I've also leveraged your conversion utilities already and
they're working nicely. Although I do see you try to convert XML
attributes into top level keys if there aren't conflicts. ;)


> I believe that if you need to include 'form field' values which are
> not explicitly defined as being required to be part of the request
> body, and therefore implicitly beyond the scope of the target api,
> that they should be sent as URL params and be part of the resource
> URI, but thats of course up to the target api to define.

Is it incorrect, either practically or theoretically, to post name/
value pairs (e.g., standard POST of encoded data) to a resource? I
guess what I'm asking is if REST would say you MUST or SHOULD post a
resource packet (properly formed XML, JSON, etc) or if posting the
name/value pairs is appropriate?

Your apiUtilities.cfc would suggest that you only ever submit a
resource as the content body (in apiPOST).


Brian

websolete

unread,
Jan 14, 2009, 11:41:11 PM1/14/09
to cfrest
See inline below:

On Jan 15, 2:05 am, Brian G <brian-goo...@vfive.com> wrote:
> On Jan 13, 11:15 pm, websolete <websol...@gmail.com> wrote:
>
> > I uploaded apiUtilities.cfc to the files section.  This is most likely
> > the equivalent of your RestConsumer.cfc.
>
> Thanks!  I've taken a look (and emailed you offline about the PUT/
> binary issue) and it helped me finalize the restconsumer.cfc I
> started.  I've also leveraged your conversion utilities already and
> they're working nicely.  Although I do see you try to convert XML
> attributes into top level keys if there aren't conflicts. ;)

Yeah, and when I saw the resulting inconsistent format between xml
with attributes and 'simple' node only xml, with no way to resolve it
short of complicating the simple xml to generify it with the
attributed version (felt wrong), I dropped using attributes for these
types of things. The work was done so the function remains just in
case there's a use case.

> > I believe that if you need to include 'form field' values which are
> > not explicitly defined as being required to be part of the request
> > body, and therefore implicitly beyond the scope of the target api,
> > that they should be sent as URL params and be part of the resource
> > URI, but thats of course up to the target api to define.
>
> Is it incorrect, either practically or theoretically, to post name/
> value pairs (e.g., standard POST of encoded data) to a resource?  I
> guess what I'm asking is if REST would say you MUST or SHOULD post a
> resource packet (properly formed XML, JSON, etc) or if posting the
> name/value pairs is appropriate?

A relevant paragraph from the wikipedia article on REST:

"An important concept in REST is the existence of resources (sources
of specific information), each of which is referenced with a global
identifier (e.g., a URI in HTTP). In order to manipulate these
resources, components of the network (clients and servers) communicate
via a standardized interface (e.g., HTTP) and exchange representations
of these resources (the actual documents conveying the information).
For example, a resource which is a circle may accept and return a
representation which specifies a center point and radius, formatted in
SVG, but may also accept and return a representation which specifies
any three distinct points along the curve as a comma-separated list."

Therefore, what you're doing is exchanging a 'representation' of the
the intended resource; while you could convey the new state of the
resource in form fields, xml and json as data exchange formats are
vastly superior to multiple string or binary form fields since you can
encapsulate a lot of different and relevant data about the resource in
a 'single' packet. It also has to do with having a consistency in the
input/output into the api so that the GET response can match closely
or exactly (if desired) the POST or PUT packet format, simplifying the
serialization/deserialization of request/responses.

I'm not sure if there are explicit rules or guidelines in REST that
prohibit the use of multiple form fields to convey representations,
but it felt wrong to me and wrapping it all up in a data exchange
format like xml/json just felt right. I won't say it was all pleasant
happy work to do it that way, but it all works seamlessly now that the
work is done and since I consume my own api in at least one other app,
I found that there was a lot of predictability in how to POST and PUT
and what I should expect back from a GET. In hindsight, I'd do it
this way again.

> Your apiUtilities.cfc would suggest that you only ever submit a
> resource as the content body (in apiPOST).

Correct.

> Brian

phenotypical

unread,
Apr 15, 2009, 12:28:32 PM4/15/09
to cfr...@googlegroups.com
Forgive me for forwarding this thread back to the list, but I don't
appear to have the option to reply (to older threads perhaps?), though
I think my question is related:

I'm building a REST api on top of a Mach-II application using SES
url's and have no problem with GET's and DELETE's and parsing the
requested resource and any arguments out of the url.

But I'm a little confused about PUT's and POST's. Specifically most
REST documentation advises to just POST or PUT the xml package as the
body, just Kevin does in appUtilities.cfc on http://groups.google.com/group/cfrest/files

...line 57, in the method apiPOST:

<cfhttp url="#arguments.resourceURL#" method="POST" result="response"
timeout="#variables.labitoolsAPITimeout#"
username="#arguments.authUsername#"
password="#arguments.authPassword#" throwonerror="false">
<cfhttpparam type="BODY" value="#arguments.requestbody#">
</cfhttp>

...but here's my question: I seem to only be able to pick something up
on the server side (i.e. in the Mach-II application) if on the client,
I set this cfhttpparam type="formfield". But I gather this is not
considered RESTful?

IOW, on the server side, in ColdFusion, how would you access the value
of that cfhttpparam of #arguments.requestbody#? It's not in the CGI
scope. Obviously not in form or url scopes. Not sure where else to
look?

Thanks in advance for any thoughts and thanks for setting this forum
up btw!

-Jason

phenotypical

unread,
Apr 15, 2009, 2:01:15 PM4/15/09
to cfrest
Ah, just stumbled upon this blog post from Mike Nimer:
http://blog.mikenimer.com/index.cfm/2006/10/2/DOJOJSON-requests-in-ColdFusion

And he shows how to get at the request body - note the last comment by
Dan Switzer to use this: toString(getHttpRequestData().content)

So this is one way to do it! :) -Jason





On Apr 15, 12:28 pm, phenotypical <jason.b...@gmail.com> wrote:
> Forgive me for forwarding this thread back to the list, but I don't
> appear to have the option to reply (to older threads perhaps?), though
> I think my question is related:
>
> I'm building a REST api on top of a Mach-II application using SES
> url's and have no problem with GET's and DELETE's and parsing the
> requested resource and any arguments out of the url.
>
> But I'm a little confused about PUT's and POST's.  Specifically most
> REST documentation advises to just POST or PUT the xml package as the
> body, just Kevin does in appUtilities.cfc onhttp://groups.google.com/group/cfrest/files

Kevin J. Miller

unread,
Apr 15, 2009, 2:23:01 PM4/15/09
to cfr...@googlegroups.com
Jason,

Yes, that’s pretty much the way.

Kevin


~ -----Original Message-----
~ From: cfr...@googlegroups.com [mailto:cfr...@googlegroups.com] On
~ Behalf Of phenotypical
~ Sent: Wednesday, April 15, 2009 9:01 PM
~ To: cfrest
~ Subject: Re: Consumer code?
~
~
~ Ah, just stumbled upon this blog post from Mike Nimer:
~ http://blog.mikenimer.com/index.cfm/2006/10/2/DOJOJSON-requests-in-
~ ColdFusion
~
~ And he shows how to get at the request body - note the last comment by
~ Dan Switzer to use this: toString(getHttpRequestData().content)
~
~ So this is one way to do it! :) -Jason
~
~
~
~
~
~ On Apr 15, 12:28 pm, phenotypical <jason.b...@gmail.com> wrote:
~ > Forgive me for forwarding this thread back to the list, but I don't
~ > appear to have the option to reply (to older threads perhaps?),
~ though
~ > I think my question is related:
~ >
~ > I'm building a REST api on top of a Mach-II application using SES
~ > url's and have no problem with GET's and DELETE's and parsing the
~ > requested resource and any arguments out of the url.
~ >
~ > But I'm a little confused about PUT's and POST's.  Specifically most
~ > REST documentation advises to just POST or PUT the xml package as the
~ > body, just Kevin does in appUtilities.cfc
~ onhttp://groups.google.com/group/cfrest/files
~ >
~ > ...line 57, in the method apiPOST:
~ >
~ > <cfhttp url="#arguments.resourceURL#" method="POST" result="response"
~ > timeout="#variables.labitoolsAPITimeout#"
~ > username="#arguments.authUsername#"
~ > password="#arguments.authPassword#" throwonerror="false">
~ >         <cfhttpparam type="BODY" value="#arguments.requestbody#">
~ > </cfhttp>
~ >
~ > ...but here's my question: I seem to only be able to pick something
~ up
~ > on the server side (i.e. in the Mach-II application) if on the
~ client,
~ > I set this cfhttpparam type="formfield".  But I gather this is not
~ > considered RESTful?
~ >
~ > IOW, on the server side, in ColdFusion, how would you access the
~ value
~ > of that cfhttpparam of #arguments.requestbody#?  It's not in the CGI
~ > scope.  Obviously not in form or url scopes.  Not sure where else to
~ > look?
~ >
~ > Thanks in advance for any thoughts and thanks for setting this forum
~ > up btw!
~ >
~ > -Jason
~ >
~ > ---------- Forwarded message ----------
~ > From: websolete <websol...@gmail.com>
~ > Date: Jan 15, 12:41 am
~ > Subject: Consumer code?
~ > To: cfrest
~ >
~ > See inline below:
~ >
~ > On Jan 15, 2:05 am, Brian G <brian-goo...@vfive.com> wrote:
~ >
~ > > On Jan 13, 11:15 pm, websolete <websol...@gmail.com> wrote:
~ >
~ > > > I uploaded apiUtilities.cfc to the files section.  This is most
~ likely
~ > > > the equivalent of your RestConsumer.cfc.
~ >
~ > > Thanks!  I've taken a look (and emailed you offline about the PUT/
~ > > binary issue) and it helped me finalize the restconsumer.cfc I
~ > > started.  I've also leveraged your conversion utilities already and
~ > > they're working nicely.  Although I do see you try to convert XML
~ > > attributes into top level keys if there aren't conflicts. ;)
~ >
~ > Yeah, and when I saw the resulting inconsistent format between xml
~ > with attributes and 'simple' node only xml, with no way to resolve it
~ > short of complicating the simple xml to generify it with the
~ > attributed version (felt wrong), I dropped using attributes for these
~ > types of things.  The work was done so the function remains just in
~ > case there's a use case.
~ >
~ > > > I believe that if you need to include 'form field' values which
~ are
~ > > > not explicitly defined as being required to be part of the
~ request
~ > > > body, and therefore implicitly beyond the scope of the target
~ api,
~ > > > that they should be sent as URL params and be part of the
~ resource
~ > > > URI, but thats of course up to the target api to define.
~ >
~ > > Is it incorrect, either practically or theoretically, to post name/
~ > > value pairs (e.g., standard POST of encoded data) to a resource?  I
~ > > guess what I'm asking is if REST would say you MUST or SHOULD post
~ a
~ > > resource packet (properly formed XML, JSON, etc) or if posting the
~ > > name/value pairs is appropriate?
~ >
~ > A relevant paragraph from the wikipedia article on REST:
~ >
~ > "An important concept in REST is the existence of resources (sources
~ > of specific information), each of which is referenced with a global
~ > identifier (e.g., a URI in HTTP). In order to manipulate these
~ > resources, components of the network (clients and servers)
~ communicate
~ > via a standardized interface (e.g., HTTP) and exchange
~ representations
~ > of these resources (the actual documents conveying the information).
~ > For example, a resource which is a circle may accept and return a
~ > representation which specifies a center point and radius, formatted
~ in
~ > SVG, but may also accept and return a representation which specifies
~ > any three distinct points along the curve as a comma-separated list."
~ >
~ > Therefore, what you're doing is exchanging a 'representation' of the
~ > the intended resource; while you could convey the new state of the
~ > resource in form fields, xml and json as data exchange formats are
~ > vastly superior to multiple string or binary form fields since you
~ can
~ > encapsulate a lot of different and relevant data about the resource
~ in
~ > a 'single' packet.  It also has to do with having a consistency in
~ the
~ > input/output into the api so that the GET response can match closely
~ > or exactly (if desired) the POST or PUT packet format, simplifying
~ the
~ > serialization/deserialization of request/responses.
~ >
~ > I'm not sure if there are explicit rules or guidelines in REST that
~ > prohibit the use of multiple form fields to convey representations,
~ > but it felt wrong to me and wrapping it all up in a data exchange
~ > format like xml/json just felt right.  I won't say it was all
~ pleasant
~ > happy work to do it that way, but it all works seamlessly now that
~ the
~ > work is done and since I consume my own api in at least one other
~ app,
~ > I found that there was a lot of predictability in how to POST and PUT
~ > and what I should expect back from a GET.  In hindsight, I'd do it
~ > this way again.
~ >
~ > > Your apiUtilities.cfc would suggest that you only ever submit a
~ > > resource as the content body (in apiPOST).
~ >
~ > Correct.
~ >
~ > > Brian
~

Reply all
Reply to author
Forward
0 new messages