Slight annoyance with argument processing

Tiburon as a service. I’ll talk about this at some point, and describe what I mean, but I have to say that I’ve been blown away by the response to it from many places and customers.

I’ve been working on making the API restful, and finally … finally … incorporating a noSQL DB on the back end to make the replication and other bits trivial. We are using MongoDB for this. And some of the designs/roadmaps we have in mind for it (Tiburon) are mind-blowing (for us).

Part of this restful processing is having a good API. We do our development in Perl and use the Mojolicious framework so we don’t have to waste time writing boiler plate code. Really, boiler plate is a waste of time, especially when someone’s done it for you. And Mojolicious is really good. Someday I think something like sails in Node will be about as painless to use as Mojolicious. And we are looking at sails for some projects. But this is a digression.

For a restful API, and hell, for any API, you need to be liberal about what you accept (everything), and conservative about what you emit. We’ll be getting JSON from some sources. So it would be nice to accept ‘application/json’ post to create objects.

So I set this up.

And spent half a day messing with it (whilst nursing a cold), trying to debug why the json wasn’t showing up in the parameter lists.

Opinionated frameworks sometimes have some interesting opinions. I had expected that JSON parameters would show up, curiously, in the list of parameters. It makes perfect sense to me that it would, with each field representing an element. But there are some JSON constructs (arrays) that would make this more complex.

So I started digging into the code and found out that JSON wasn’t being parsed in the parameter pathway. I wasn’t able to catch precisely where it was processed and emitted (docs were unclear on this).

So I asked on the list, and got one response that was off. Fine, I delved into it more. Traced it out, and saw what was happening.

There was a deep element in object that had this. I couldn’t see how to easily get it without a deep (and horrible) dereference chain. So I posted this again on the list with what I found.

A better suggestion emerged from the creator of the code, and we’ll give it a test, make sure it does what we need. But still, it seems odd to me to provide multiple different pathways to getting parameters in. I look at form or json as a transport format for the values, and I’d like them to all show up in the same place. So I wrote a little method to handle that, and now everything is where it should be and I can work again.

 
sub get_any_arg_types_into_hash {
  my $self	= shift;
  my @params = $self->param;
  # evil access  UGH!!!
  #my $json_arg_string   = $self->{tx}->{req}->{content}->{asset}->{content};
  # may not need the below
  my $json_arg_string   = $self->req->body;
  my $content;
 
  # copy parameters into content hash
  if (@params) {
    foreach my $p (@params) {
      $content->{$p} = $self->param($p);
    }  
   }
  else
   {
    $content = $self->req->json;
   }
  return $content;
}

The side effect of this effort was a major simplification of the code to pull in arguments. So all was not lost. But I did get to spend half a day with a debugger, delving into other peoples code.

That is worthy of a post in and of itself … but its worth noting that I write code thinking that I won’t quite remember what I needed to do in 6 months, so I damned well better write clear and unambiguous code, with comments describing the important aspects. I really wish everyone did that.

Viewed 32873 times by 2600 viewers