Knuth on reusable code

Today via Lobsters: APL Style: Patterns/Anti-patterns:

I also must confess to a strong bias against the fashion for
reusable code. To me, “re-editable code” is much, much better
than an untouchable black box or toolkit. I could go on and on
about this. If you’re totally convinced that reusable code is
wonderful, I probably won’t be able to sway you anyway, but
you’ll never convince me that reusable code isn’t mostly a
menace.

— Donald Knuth, Interview with Andrew Binstock

“REST” interfaces

I just wanted to get something that I’ve thought for many years on record, because I don’t think I’ve ever had the chance to discuss it much before, but I believe JSON web services (“REST APIs”) and web applications should deal only in two HTTP verbs, being: GET and POST. You use GET for queries and you use POST for submissions. All POST operations go through business logic for particular services and CRUDing URLs is a supremely bad idea, in my opinion. Just wanted to get that on record. Thanks. p.s for web applications you should 3xx on success, not 2xx on success; what you do for JSON web services is up to you, but for those 2xx is probably fine.

Best practices for REST API design

Over on the StackOverflow blog: Best practices for REST API design. Some of it is good but I disagree with a bunch of things. I made some notes:

* Use singular

https://www.example.com/comment/list

Not:

https://www.example.com/comments


* Use multidimensional selectors, not path/hierarchical selectors:

https://www.example.com/comment/list?artist=nirvana&album=nevermind

Not:

https://www.example.com/album/nirvana/nevermind/comments


* Use noun/verb format:

https://www.example.com/comment/list
https://www.example.com/comment/register
https://www.example.com/comment/edit/54688
https://www.example.com/comment/view/54688
https://www.example.com/comment/reply/54688


* The [ noun, verb ] pairs map to Facilities for implementation:

[ comment, list ] => CommentLister
[ comment, edit ] => CommentEditor
[ comment, view ] => CommentViewer

Facilities have submit/render functionality and round-trip view state.


* HTTP success 30x's not 2xx's.


* Include a 'submission ID' on <form> elements for idempotent operations


* GET and POST only, don't CRUD URLs, rather invoke business processes

How to iteratively create PhoneGap contacts

I started a new project today to load the contacts from my personal database into my iPhone.

cd ~/Documents/pcrepo/aman-importer
phonegap create phonegap-test
cd phonegap-test
phonegap platform add ios
phonegap plugin add org.apache.cordova.contacts

There is documentation for the Contacts API.

The trouble I got into was iteratively creating contacts.

Code like this doesn’t work:

for ( var i in contact_data_list ) {
  var contact_data = contact_data_list[ i ];
  var contact = navigator.contacts.create();
  var name = new ContactName();
  name.givenName = contact_data.first_name;
  name.familyName = contact_data.last_name;
  contact.name = name;
  contact.save(
    function() { alert( 'saved!' ); },
    function() { alert( 'failed!' ); }
  );
}

The behavior is that contact.save fails and neither of the success or failure callbacks are invoked.

The way to iterate over the input data is like this:

var index = 0;
var saver = function() {
  if ( index === contact_data_list.length ) {
    // we're finished enumerating the array, we can report and exit:
    navigator.contacts.find( ['*'], report_contacts );
    return;
  }
  var contact_data = contact_data_list[ index++ ];
  var contact = navigator.contacts.create();
  var name = new ContactName();
  name.givenName = contact_data.first_name;
  name.familyName = contact_data.last_name;
  contact.name = name;
  contact.save(
    saver,
    function() { alert( 'failed!' ); }
  );
};
saver();

You can see it for real over here

Amazon Web Services (AWS) — Elastic Compute Cloud (EC2)

Learning how to program the EC2 system via the PHP API. I needed to know about RunInstances and AssociateAddress.

You can send Amazon a Request to Remove Email Sending Limitations which by default limit the amount of email traffic instances can process.

Also read about Amazon EC2 Instance IP Addressing and Elastic IP Addresses (EIP).

Although I settled on using the PHP SDK I read the doco for the Java SDK EC2 client: Class AmazonEC2Client. The corresponding PHP API is here. Also How to get list of EC2 instances with Amazon PHP SDK 2 from StackOverflow was useful. All AWS SDKs are here and there are command-line tools. There is AWS SDK for PHP Documentation. This article Provision an Amazon EC2 Instance with PHP was a handy starting place. I also saw the Amazon Elastic Compute Cloud API Reference. I also read AWS SDK for PHP: Run an Amazon EC2 Instance.

I started a project at ProgClub called make-love, which is my server re-instantiation script. It shows how to use the AWS PHP SDK and the r53.php code for programming AWS Route53 DNS services. Documentation on the Route53 client can be found at Ordering Disorder. More on r53.php at SourceForge. I added a new function listAllResourceRecordSets to the Route32 class and commented out some SSL validation code because validation was failing and it’s no big deal to ignore it.

GeoIP with MaxMind’s GeoLite in PHP

You can download the GeoLite Country database from GeoLite Free Downloadable Databases and you can grab the MaxMind GeoIP PHP API.

Once you have the GeoIP.dat file and the geoip.inc PHP file you’re good to go. E.g.:


  require_once __DIR__ . '/geoip/geoip.inc';

  $gi = geoip_open( __DIR__ . '/geoip/GeoIP.dat", GEOIP_STANDARD );

  $country_code = geoip_country_code_by_addr( $gi, $host );
  $country_name = geoip_country_name_by_addr( $gi, $host );

  geoip_close( $gi );