POSTing multiple objects

69 views
Skip to first unread message

Richard Poole

unread,
Jan 22, 2014, 2:31:04 AM1/22/14
to taffy...@googlegroups.com
Hi Adam,

I'm nearing the completion of our API (100+ calls so far!) and one thing that I'm not happy with in my current code is how I handle adding multiple entities. Take the example of adding a contact with firstname & lastname:

<cfargument name="firstname" type="string" required="true" hint="First Name."/>
<cfargument name="lastname" type="string" required="true" hint="Last Name."/>

At the moment if I want to add more than one then I either have to make this call a heap of times (not good when I might want to use this to import 1000+ contacts) or I ask the user to separate the list of names with a delimiter (choosing wisely so this won't occur in the data itself). 

Ideally what I'd like to do is to be able to accept single contacts like this:
{ "firstName":"John" , "lastName":"Doe" }

and multiple contacts like this:
[
{ "firstName":"John" , "lastName":"Doe" }, 
{ "firstName":"Anna" , "lastName":"Smith" }, 
{ "firstName":"Peter" , "lastName":"Jones" }
]

I might be missing something obvious but the only way I can currently see to do this is to require that the data is submitted as:

{
"contacts": [
{ "firstName":"John" , "lastName":"Doe" }, 
{ "firstName":"Anna" , "lastName":"Smith" }, 
{ "firstName":"Peter" , "lastName":"Jones" }
]
}

but that means I can't take advantage of taffy's dash for the argument hints which would be a bit of a blow as I have documented the crap out of them!

Any advice? Hoping it's just my relative lack of CF knowledge and too many late nights that are making me miss something obvious :)

Cheers,

Richard

Adam Tuttle

unread,
Jan 22, 2014, 6:54:36 AM1/22/14
to taffy...@googlegroups.com

Version 2.2, released yesterday, adds support for non-struct request bodies. It will pass a new argument named _body to your resource with the array that the user posted. Good? :)

--
You received this message because you are subscribed to the Google Groups "Taffy Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to taffy-users...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Adam Tuttle

unread,
Jan 22, 2014, 8:54:00 AM1/22/14
to taffy...@googlegroups.com
Sorry for my brevity earlier. I was answering on my phone from the relative comfort of the electric blanket before getting out of bed. :)

So in your resource(s) where you want to pass an array, just do it. You don't even need to declare a new "_body" argument to the methods; it'll still show up:

function post(a,b,c,d){
  if structKeyExists(arguments,'_body'){
    for (var x in arguments._body){
      handlePost(argumentCollection=x);
    }
  }else{
    handlePost(argumentCollection=arguments);
  }
}

private function handlePost(a,b,c,d){...}

That ought to do it. Apologies if there are any errors, this is untested code. :)

Adam

Richard Poole

unread,
Jan 22, 2014, 1:41:52 PM1/22/14
to taffy...@googlegroups.com
Hi Adam,

Worked like a charm, Taffy Dash didn't like it ("Looks like you're sending JSON data, but you haven't specified a content type. Aborting request.") but works great in actual testing so far :)

Cheers,

Richard

Jesse Franceschini

unread,
Feb 27, 2014, 6:55:56 PM2/27/14
to taffy...@googlegroups.com
I stumbled across this because I'm wondering about namespacing POST inputs and this seems like a plausible solution.

I'm trying to keep attributes from the POST body from polluting URI tokens. Say I have an API with a URI token of /teams/{team_id}/members. If I try to add a member to this team with a POST, I could mess up the {team_id} token by passing an attribute called "team_id" in via the body of the request. Maybe I'm incorrect in fretting over this, but it seems like unwanted behavior.

Anyway, seeing your solution for Richard's problem made me think that all POST body content should be stuffed into "_body" no matter what, just to make sure they're separate from other variables that taffy populates. I changed a handful of lines in my local taffy instance and it seems to be working as expected, but I figured I'd mention this subject in case I'm going about this all wrong.

Adam Tuttle

unread,
Feb 28, 2014, 10:10:50 AM2/28/14
to taffy...@googlegroups.com
I see your point, and I'm willing to have the discussion.

The way it works right now is that if a body argument has the same name as a uri token, the body argument takes precedence. This is, in part, inspired by FW/1 (and the things that inspired it)... they mash all incoming data into a "request context" (rc), so if you get both a url variable and a form variable that have the same name, one has to take precedence.

I still believe that what we're doing currently is correct (if you really need them to be separate, change the name of one of them)... but I will entertain any dissent and arguments that the precedence should be switched. Just be prepared to defend your position! :)

Adam

Jesse Franceschini

unread,
Apr 3, 2014, 7:06:32 PM4/3/14
to taffy...@googlegroups.com
if you really need them to be separate, change the name of one of them

Ah, but what if we have an enterprising user fussing around with API calls and crafting inputs by hand. The inputs aren't necessarily in our control, they are free to format the request body in any fashion they can think of. And if any of their attributes conflict with URL tokens or parameters, unexpected behavior can result. If the inputs are namespaced based on their source (request body, URL parameters, URL tokens, etc), then we would have some control over potential conflicts. 

I'd say this concept comes straight from ColdFusion itself. Isn't that the purpose of the FORM scope and the URL scope (at least partially)? Multiple sources of input are bucketed according to where they come from so that they don't pollute each other if the attributes are similar.

But I know it would complicate things. One thing that's nice is just throwing everything into an argumentCollection and knowing that everything will be there on the other side. Having everything scoped like this would break a lot of legacy code I'm sure, so I'm not willing to die on this hill. Just making the argument.

Adam Tuttle

unread,
Apr 3, 2014, 7:47:36 PM4/3/14
to taffy...@googlegroups.com
What I meant was to change the token name. If you've got someone submitting body arguments all willy-nilly (are you just logging everything they're sending you? Otherwise I find it odd that you're not specifying the accepted arguments...), you could change your token names to be uri_token_foo so that it won't conflict with the foo that they send in the body.

Adam


For more options, visit https://groups.google.com/d/optout.

Jesse Franceschini

unread,
Apr 4, 2014, 3:07:28 AM4/4/14
to taffy...@googlegroups.com
Ah, I see what you're saying.
Reply all
Reply to author
Forward
0 new messages