Wednesday, December 31, 2014

RESTful APIs with Bedrock (part V)

This is the 5th in a series of blogs on using Bedrock to create a RESTful API.  So far we've checked off several requirements for building a RESTful API.  We've been able to demonstrate the basics of creating a RESTful API using Apache and Bedrock.  We've satisfied requirements #1 through #4 and #6.
  1. Parse a URI
  2. Determine the operation to be performed
  3. Determine the result format requested by the client
  4. Retrieve, validate, and de-serialize client data
  5. Retrieve data from the back end
  6. Serialize data to send back to client
  7. Set HTTP response headers
  8. Handle errors
We'll round out the discussion by showing how Bedrock can satisfy the 3 remaining requirements.

Tuesday, December 30, 2014

RESTful APIs with Bedrock (part IV)

To recap our 8 requirements of a web development framework for creating our RESTful API:
  1. Parse a URI
  2. Determine the operation to be performed
  3. Determine the result format requested by the client
  4. Retrieve, validate, and de-serialize client data
  5. Retrieve data from the back end
  6. Serialize data to send back to client
  7. Set HTTP response headers
  8. Handle errors

In yesterday's blog we talked about using Apache directives to help us create meaningful URIs and using Bedrock to interpret the extra path information and HTTP method in order to satisfy requirements 1 & 2.

Today we'll examine #3 and #4 and touch on #6.

Monday, December 29, 2014

Perl Regular Expression Capture Groups

After cursing Bedrock for not giving me access to capture groups in regular expressions, I finally bit the bullet and figured out how to implement this in a somewhat sane manner.

RESTful APIs with Bedrock (Part III)

The other day I blogged about using Bedrock to create a RESTful API.  Today I'm going to talk about setting up Apache in order to support a RESTful interface based on URIs.  Last time we pulled these requirements for a REST API framework from Michael McClennen's talk:

  1. Parse a URI
  2. Determine the operation to be performed
  3. Determine the result format requested by the client
  4. Retrieve, validate, and deserialize client data
  5. Retrieve data from the back end
  6. Serialize data to send back to client
  7. Set HTTP response headers
  8. Handle errors

Let's configure Apache to help us with #1, and #2 as we implement a hypothetical RESTful interface for a contact database.

First, we'll create an Apache RewriteRule that maps our desired API's base URI to a Bedrock page.  We add the directives below to our Virtual host configuration file.

RewriteEngine On
RewriteRule  ^contacts(/.*)?$ rest-api/contacts-api.jroc/$1

Using this rule URIs that begin with contacts will now be rewritten to point to a URI that implements our REST interface in Bedrock.  The Bedrock file contacts-api.jroc is a Bedrock script (page) that returns a document of type application/json.  By convention (and as implemented by the Bedrock handler), any Bedrock script with an extension of .jroc will be considered to return a JSON document.

That's just another way of saying that Bedrock will set the mime-type header to application/json for you automatically.  Of course you could have named the file contacts-api.roc and then set the Content-Type header yourself.

<null $header.set('Content-Type', 'application/json')>

Files in the rest-api directory are configured using Apache directives so they will be processed by the either the Bedrock mod_perl Apache handler or the Bedrock handler implemented as a CGI.

<Directory /var/www/vhosts/myhost/htdocs/rest-api>
# Bedrock - mod-perl for .roc (if mod_perl)
  <IfModule mod_perl.c>
    AddHandler    perl-script .roc .jroc .html
    PerlHandler   Apache::Bedrock
  </IfModule>

  Action bedrock-cgi /cgi-bin/bedrock.cgi virtual

  <IfModule !mod_perl.c>
    AddHandler    bedrock-cgi .roc .jroc
  </IfModule>
...
</Directory>

We can now use the PATH_INFO environment variable to interpret our URI since all the stuff after  contacts/ in our URI will be considered extra path information and presented to us in that environment variable...well sort of.   As it turns out, when Bedrock is configured using the CGI version, PATH_INFO will contain the filename (contacts-api.jroc) as well as the extra path info.  For this reason, Bedrock provides an environment variable named BEDROCK_PATH_INFO only available when the Bedrock handler is configured as a CGI script that contains only the extra path information.

PATH_INFO => (/env.roc/foo)
BEDROCK_PATH_INFO => (/foo)

Our REST API script can now grab the extra path information necessary for us to interpret the URI.

<null:path_info --default=$env.PATH_INFO $env.BEDROCK_PATH_INFO>

Under mod_perl we'll use the PATH_INFO variable, but as a CGI handler we'll use the value Bedrock provides as BEDROCK_PATH_INFO.  Since the BEDROCK_PATH_INFO variable is only set when the Bedrock handler is a CGI, our $path_info will be set  using the default value under mod_perl.

The URI gives us the context, but what about the method?  Using Bedrock's $env object that exposes  environment variables to your Bedrock pages, we can examine the HTTP method sent by the client.  By testing  $env.REQUEST_METHOD we can determine the HTTP method.  The value will probably be either GET, PUT, POST, or DELETE, as set by the client and defined by your API.  It would then be easy enough to test that value along with the URI to determine the operation to be performed.  That is to say, the operation to be performed will be a function of the HTTP method and the URI.

<if $env.REQUEST_METHOD --eq 'GET'>

# /contacts/friends
   <if $path_info --eq '/friends'>
   ...
   <elseif $path_info --eq '/business'>
   ...
   <else>
     <raise '400'>
   </if>

<elseif $env.REQUEST_METHOD --eq 'PUT'>
...
</if>

This now satisfies our first two requirements we discussed last time, namely:
  • Parse a URI
  • Determine the operation to be performed
Next time: Determining the result format and de-serializing our input data.

Wednesday, December 24, 2014

RESTful APIs with Bedrock (Part II)

Reading the Perl blogs I saw a link to a Michael McClennen RESTful talk.  It was an interesting introduction to those with no background on REST and offered some insights and interpretations based on his experience.  The talk does a good job balancing an informational talk on RESTful interfaces in Perl with a gentle sales pitch for his new CPAN module (Web::DataServices).

First off, anyone that publishes on CPAN has my great respect.   Clearly this author knows his stuff, shares it and that's a very good thing.   I'm not sure I will become a user of this module, primarily because of the dependencies (Moo, etc), but more to the point I'm not (yet) convinced one needs a complete RESTful framework that sits on top of a web development framework.

Having said that, I reserve the right to change my mind and I imagine the author spent a lot of time thinking of that as well and ultimately concluded this his effort was worthy of the problem.   Congrats to Michael on publishing his module and adding another building block or at least reference for Perl developers.  I admire that effort and wish I had the time and energy to do the same.

So, do we really need a RESTful API framework?


I'm not sure.  Why don't I think we need a RESTful framework?  Well, I would hope that that the web framework itself that was chosen is robust enough to implement the RESTful architecture and your API without a lot of overhead or hair pulling.  After all, the RESTful architecture is supposed to reflect the stateless and simple nature of the web.  Sort of, I guess.  Paraphrasing a slide from Michael's presentation, there's not too much one needs from a framework to produce a RESTful API.  Here's what we'd like from our framework in order to implement our API.

Thursday, December 4, 2014

A RESTful API Using Bedrock?

As I've written before, writing AJAX services in Bedrock is actually pretty trivial.  In fact, Bedrock's support of the .jroc extension which automatically sets the mime-type of the output to application/json makes creating an AJAX widget to return the current environment for example, look something like this:

<var --json $env>

Not sure how it could get any easier than that...and with a properly configured Bedrock installation, AJAX services that access information stored in MySQL tables is equally as easy.

<sqlselect "select * from customers" --define-var"customers"></sqlselect>
<var --json $customers>

I've recently started looking at using Bedrock to prototype a RESTful interface and I've been very encouraged about the simplicity here as well.  Several features of Bedrock make creating a RESTful API pretty easy.


  • Ability to interpret the environment variables (URIs), etc.
  • JSON
  • Access to POST data
  • Ability to directly set status
  • Ability to interpret and set HTTP headers


I've been studying up on creating robust, secure and compliant RESTful interfaces and think I can use Bedrock to prototype a RESTful API.  Some interesting resources I've found so far include:

REST Video Tutorial
REST API Design Rulebook
API Security Considerations

So what might a Bedrock based RESTful API look like anyway?  Consider this API:

/accounts      => returns a collection of accounts
/accounts/{id} => returns a single account's record
/books         => returns a collection of books
/books/{id}    => returns a single book record

Let's give this a shot in Bedrock...

<sink><null:uri $env.BEDROCK_URI>
<null:parts $uri.split('/')>

<hash:out>

<if $parts.[1] --eq 'accounts'>
 <if $parts.[2]>
   <sqlselect "select * from account where id = ?"
              --define-var="out"
              --bind=$parts.[2]></sqlselect>
 <else>
   <sqlselect "select * from account" --define-var="out></sqlselect>
 </if>

<elseif $parts.[1] --eq 'books'>
  <if $parts.[2]>
    <sqlselect "select * from book where id = ?"
               --define-var="out"
               --bind=$parts.[2]></sqlselect>
  <else
   <sqlselect "select * from book" --define-var="out></sqlselect>
  </if>

</if></sink><var --json $out>

Okay, this is a really simple and featureless example that doesn't consider authentication, or setting status on error, but you get the idea.  I'll be blogging about this subject as soon as I do the deep dive, but it looks promising.

Acer C720 Demand Sparks Price Increase

Apparently I'm not the only one that thinks the Acer C720 is the best damn Chromebook you can get for the money.  The price and availability this Christmas are moving in opposite directions.

Prices are going up, and the stock and availability are going down.

Yes, I'm pimping this product, because I love me some Chromebook!  I literally use this device every day and yes I am writing this blog on my Acer C720 Chromebook (11.6-Inch, 2GB).

 Full disclosure...I've made about $20 after a year of blogging about this product using the Amazon Associates links - so apparently I'm not very good at it, my blog is not that popular and I'm clearly not making a living at this. Note to self, don't quit your day job. The links are really for your convenience, just in case you feel the urge and need a push. ;-)

Love me some Chromebook!


I may just re-moniker this blog Love Me Some Chromebook!  But honestly, this is an extremely easy product to fall in love with for anyone that wants a low cost, well made device for email, browsing, watching videos and even doing software development in the cloud.  Fast boot, long battery life, and light weight, I take this puppy EVERYWHERE!   No, it doesn't run Microsoft Office, but this is 2014 people!  Stop the MS Office malarkey already!

Google Docs and Google Sheets are absolutely awesome and you are doing yourself and your grand kids a disservice if you continue to pound that damn MS Office drum.  Ever watch a 14 year old write a paper for school on Microsoft Word?  They spend the first 20 minutes adjusting margins, font-size and the font face in order to make 3 paragraphs of drivel expand into a 2 page Hemingway masterpiece.
"Everything is your fault...if you're any damn good!" - Ernest Hemingway
 Buy your kids a Chromebook and teach them to write instead of format.   But that's America these days, style over substance I guess...if they have to hand in an MS Office paper, they can save their Google Doc as an MS Word file.

Still not convinced?  Don't buy a Chromebook, just install Chrome on your Windows machine and play with Google Docs/Sheet/and Slides.  Print to a cloud enabled device (see my reviews and howto's from last year)...and then decide.  It's been a year with my Chromebook and the honeymoon is definitely not over.  It just gets better with every update.  Which happens transparently for me by the way!

As of today (December 4th, 2014), the device is out of stock at Amazon but they claim it will ship in a few days.

I'm still doing some research and will blog on this subject (performance) soon, but I've concluded that the Acer C720 is not just a good Chromebook, it is THE Chromebook.  Why?  I'll summarize my research by saying, it's simply the best value.  It uses the best CPU for the money (Intel Celeron 2955u)  and still delivers exceptional battery life while keeping the cost under $200...well it was under $200 until this morning.  Hopefully as stocks are replenished you can grab one at a lower price.

CAUTION!  Don't be fooled with other Chromebooks that claim higher clock speeds. That DOES NOT TELL THE WHOLE STORY.  Read the reviews.  If it ain't using the 4th Generation Haswell architecture 2955U it's either an ARM processor or an Intel M-series (Baytrail architecture) and the performance will not match the Acer C720.  The exception being the Acer C720 with the i3 processor.  You'll get slightly better performance with that device, but at a higher price point.  

If streaming music and video while you're doing other tasks is important to you, then this C720 will give you the ultimate experience.  I've been listening to Earbits Radio streamed to my iSound Twist Bluetooth Wireless Mobile Speaker (Rubberized Blue) with more than 6 tabs open while writing this blog on my plain 'ol 2955U based C720 with just 2MB.  If you typically run with a lot of tabs open, you might want to consider the Acer C720-3404 11.6-Inch Chromebook (Intel Core i3, 4 GB) Granite Gray version of the C720.   If I get carried away, I have been able to crash a tab or two and run out of memory.

If you are considering a Chromebook, my advice after a LOT of research is that you will not find a better Chromebook for the money right now.  I keep looking, but right now, the Acer C720 is hands down the best Chromebook on the market.  Don't take my word for it though, go try to find one right now!  Good luck.