Own your endpoints

If URLs are people too then you better make sure you control your URLs.

Although some people use blog hosting services like blogger the majority of serious bloggers, web designers or companies generally use their own domain name to host their site. Controlling your own domain name is increasingly important when that URL is a representation of you on the internet.

With all these social networks we’re starting to have pieces of us scattered all over the place. I’ve joked previously about the utility of domain names over real names for interpersonal communication but this breaks down a little when not all the urls that represent me are owned by me. I control morethanseven.net/photos but I only have some influence over flickr.com/photos/garethr. With external hosts you also need to be aware of cybersquatting. I own morethanseven.net so no one else can use it. However with services that give you your own URL as part of registration everywhere people can cybersquat in hundreds of new domains that you might not even know about.

It’s not just web pages you have to worry about. Feeds are another example of URLs you just might want to keep control over. This last one is also something I see lots of people handing off to others - specifically Feedburner. Now I’m a big fan of feedburner and use it for the feeds on this site. But I don’t use the feedburner URL, anyone subscribing to the feeds here does so using morethanseven.net/feed/. If I decide to stop using feedburner I can, without having to upset the few people who subscribe to it by moving my feed address. It’s the same with email addresses; I love gmail but rarely actually give my gmail email address out.

So, start looking after your domain names a little more carefully. They are pieces of you scattered around the internet, and losing control of them is going to become increasingly socially painful.

Accepted for Xtech

So, while sat with a few people at the WaSP panel at SXSW (of which more later when I’m fully caught up) I got a nice email from the folks at Xtech accepting my presentation idea. The abstract is below. If any of that sounds interesting or up your street I’d love to hear other peoples experiences or ideas on the subject.

Design Strategies for a Distributed Web

From language frameworks to APIs

Everyone is making use of mature and stable web application or javascript frameworks these days. That means we’ve stopped reinventing things such as routing and object relational mapping, but we’re all still building very similar components again and again. Frameworks might allow us to solve lots of fine grained problems but APIs could let us solve common course grained problems quicker.

Building blocks for your applications

Their are already a few examples in the wild of APIs designed to be used as part of your application development process. Amazon has been leading the way in providing remote services such as S3, EC2 and SimpleDB. Their are also options when it comes to hosting these services yourself, the mint analytics software and the CouchDb database service are both good examples.

Quality engineering for free

The real value of outsourcing a discreet portion of your application to a third party API lies in quality. You could always use local storage and your programming language of choice to deal with a large volume of file read and write operations. But do you really think you’ll beat Amazon for reliability, scalability and speed?

Functionality vs Data

It’s not just high quality functionality that we could leverage from other providers. We’re all fed up with entering and re-entering our personal data into each new service. With advancements like OAuth and Microformats and lots of focus on data portability at the moment we might just be able to share data too.

Change the client as well as the server

Sometimes it’s not enough to just change the server. The rise of specialised browsers such as Joost and Songbird allows for functionality that would be impossible otherwise. Site specific browser, along with advancements such as local storage, may prove Problems

It’s not all in place just yet. The reliability of your application is likely to be important, and making use of a distributed set of APIs could leave you in the unenviable position of being less stable than your least stable partner. The issue of lock-in could also raise it’s head, without a vibrant ecosystem of different providers that is.

The Future

The use of third party commercial APIs has the potential to change the development landscape – bringing high quality middleware to the web. It could be the original web services dream realised. But without critical mass and an active market it could also be a new achilles heel for successful startups.

Generating Charts using Google Charts API

I had need recently to produce some nice looking charts and immediately turned to the very nice Google Charts API. Just before Christmas Brian had written up a great introduction on 24ways and ever since I’d been looking for an excuse.

Chris wrote up a pretty nice approach to enhancing well marked up data tables using the Charts API with a dash of Javascript and I decided to start with that. I made only a couple of changes to this approach based on personal requirements and preferences.

For a table like this:

Caption

Label

Data

Label

Data

I prefer to use the table header element to mark up the table row and the original script relied on these being td elements. A couple of changes to the javascript fixed that. I also decided to display the caption as a title on the resulting graph.

<code>
<table class="tochart">
  <caption>Caption</caption>  
  <tr>
    <th scope="row">Label</th>
    <td>Data</td>
  </tr>
  <tr>
    <th scope="row">Label</th>
    <td>Data</td>
  </tr>
</table>
</code>

The original script only supported the 3D pie charts and in a couple of cases I wanted to generate bar-charts from the data or flat pie-charts. A few modifications later and you can pass a type parameter into the script via a class on the table.

The default if the parameter isn’t set is the flat pie-chart, which can also be specified via:

<code><table class="tochart typep"></code>

For the 3D pie-chart:

<code><table class="tochart typep3"></code>

The horizontal bar-chart is created with:

<code><table class="tochart typebhg"></code>

And finally the vertical bar-chart is set based on:

<code><table class="tochart typebvg"></code>

The complete modified version of Chris’ script is below:

<code>(table2graph = function(){

  /* variables */
  var triggerClass = 'tochart';
  var chartClass = 'fromtable';
  var hideClass = 'hidden';
  var chartColor = 'FFCC33';
  var chartSize = '900x300';
  var chartType = 'p';

  var toTableClass = 'totable';
  var tableClass = 'generatedfromchart';
  /* end variables */

  var tables = document.getElementsByTagName('table');
  var sizeCheck = /\s?size([^\s]+)/;
  var colCheck = /\s?color([^\s]+)/;
  var typeCheck = /\s?type([^\s]+)/;
  for(var i=0;tables[i];i++){
    var t = tables[i];
    var c = t.className;
    var data = [];
    var labels = []
    if(c.indexOf(triggerClass) !== -1){
      var size = sizeCheck.exec(c);
      size = size ? size[1] : chartSize;
      var col = colCheck.exec(c);
      col = col ? col[1] : chartColor;
      var type = typeCheck.exec(c);
      type = type ? type[1] : chartType;

      if (type == 'bhg') {
        var label = 'chxl=1:|';
      } else {
       var label = 'chl=';
      }

      var caption = t.getElementsByTagName('caption')[0].innerHTML;
      var charturl = 'http://chart.apis.google.com/chart?cht=' + type + '&chtt=' + caption + '&chxt=x,y&chco=' + col + '&chs=' + size + '&chd=t:';
      t.className += ' '+ hideClass;
      var ths = t.getElementsByTagName('tbody')[0].getElementsByTagName('th');
      var tds = t.getElementsByTagName('tbody')[0].getElementsByTagName('td');
      for(var j=0;tds[j];j+=1){
        labels.push(ths[j].getElementsByTagName('em')[0].innerHTML.toLowerCase());
        data.push(tds[j].innerHTML);
      };
      var chart = document.createElement('img');
      chart.setAttribute('src',charturl+data.join(',') + '&' + label + labels.join('|'));
      chart.setAttribute('alt',t.getAttribute('summary'));
      chart.className = chartClass;
      t.parentNode.insertBefore(chart,t);
    };
  };

  /* convert charts to tables */
  var charts = document.getElementsByTagName('img');
  for(var i=0;charts[i];i++){
    if(charts[i].className.indexOf(toTableClass) !== -1){
      var t = document.createElement('table');
      var tbody = document.createElement('tbody');
      var data = charts[i].getAttribute('src');
      var th,td,tr;
      var values = data.match(/chd=t:([^&]+)&?/)[1];
      var labels = data.match(/chl=([^&]+)&?/)[1];
      var l = labels.split('|');
      var v = values.split(',');
      for(var j=0;l[j];j++){
        tr = document.createElement('tr');
        th = document.createElement('th');
        th.appendChild(document.createTextNode(l[j]));
        th.setAttribute('scope','row');
        td = document.createElement('td');
        td.appendChild(document.createTextNode(v[j]));
        tr.appendChild(th);
        tr.appendChild(td);
        tbody.appendChild(tr);
      };
      t.appendChild(tbody);
      t.setAttribute('summary',charts[i].getAttribute('alt'));
      charts[i].parentNode.insertBefore(t,charts[i]);
      charts[i].setAttribute('alt','');
      t.className = tableClass;
    };
  };
}());</code>

Thinking Digital

I’m starting to get excited about Thinking Digital. But first a bit of back-story.

I started out making the trip to @media 2005 and since then have been a regular attendee of more conferences than I can shake a stick at. Lets say I caught the conference bug. But most of those have been within the web standards community niche and more recently I’ve been looking further afield for conference kicks, party due to the eclectic nature of BarCamp style events. Anyone in that positions inevitably takes a fancy to going along to TED. The only problem is the fact it’s already booked up until 2010, costs $6,000 just to for a standard membership and is invite only.

This year the folks over at Codeworks, which is a regional body set up to help us North East digital folk develop an industry, are organising their very own full size conference. The Think and a Drink events have been running for a number of years and I’ve spoken a few times on web related bits and pieces. But these are purposely local events mainly for members and tend to crop up at the rate of once a month. Thinking Digital is a full size, 400 person, conference being held in Newcastle between the 21st and 23rd of May this year covering a similar set of wide ranging themes to TED; technology, design, mobile plus a bit of philosophy and futurism thrown in for good measure.

Now this is good for a few reasons. Only one of which is I can see the venue out of my apartment window. Costing only £475 and being in the UK would be a couple of other reasons to get excited. As an aside; I’m helping out as a board member along with the likes of Ian Forrester but I’d gladly pay my way if I wasn’t.

The real reason for the excitement though is the calibre of some of the speakers. Ray Kurzweil, Greg Dyke, Dan Lyons (a.k.a. Fake Steve Jobs), Matt Locke, Aubrey De Grey and Tara Hunt to name a few I’m particularly interested in. And remember folks, this is in Newcastle. Which for the few Londoners reading is a couple of hours North of you. On a train with free wifi even.

Now this might not be a web conference but I’m pretty interested in the take of the likes of Ray Kurzweil on the web and what will happen in the near future. I’m also interested in the types of people who will make the trip - which is really the reason for this post. As everyone knows, one of the best parts of any conference is the chance to chat with like-minded (and not so like-minded) folks. So, who fancies coming along?

Sorry, but the Flickr API isn&#39;t REST

After SemanticCamp me and Rey popped in to see Paul and everyone at Osmosoft towers. A good few interesting conversations ensued, including one about the difference between mashups and integration. All good fun basically. Simon also had an interesting take on the topic as well.

What has all this to do with the topic of this post? Well, Simon says:

When compared to small RESTful APIs like flickr and twitter…

Now I’m not really picking on Simon here, more that I’ve been meaning to write something on this topic for a while and this proved a good catalyst for a little rant.

The flickr API is pretty darn cool. But it’s not RESTful in pretty much any way you want to shake a stick at it. It’s a well designed RPC (remote procedure call) API. Now even flickr get this wrong. They even have a page which confuses the issue and makes REST out to be a response format based on XML. Bad flickr.

flickr states that:

The REST Endpoint URL is http://api.flickr.com/services/rest/

This turns out to be completely against the whole RESTful principles. Lets try and explain. You can define most of what you want to do with an API with the use of nouns, verbs and content types. REST is based around limiting the set of verbs to those available in HTTP; for instance GET, POST, PUT and DELETE. For any given application or API you’ll also specify a set of content types (representations); for instance HTML, JSON or XML. All you get to play around with are the nouns, in the case of the web these are our URLs.

In a typical RPC style API you have one URL (like flickr does) which acts as the end point to which all calls are made. You then probably define a few functions which you can call. Lets look at a simple book example.

<code>getBook()
deleteBook()
createBook()
editBook()</code>

The RESTful way of designing this might look a little bit more like this:

<code>GET     /books/{book-id}
DELETE  /books/{book-id}
POST    /books
PUT     /books/{book-id}</code>

We mentioned content types or representations earlier. Lets say instead of the default response format we might want to get a JSON representation of a given book we might do something like the following.

<code>GET /books/{book-id}.json</code>

The advantages of using URLs as the API nouns in this way include more than just sane URLs for the site or application in question. The web is based around many of these architectural principles and that seemed to scale pretty well. The idea is that fell envisaged RESTful applications have an advantage here too. For me one of the real benefits of RESTful APIs are in the simplicity they bring to documentation. I already know the available verbs, all I need to know are the set of resource URLs and I can probably use CURL to work out the REST (sorry, bad pun).

This misunderstanding is pretty common. Even WikiPedia appreciates their is a problem:

The difference between the uses of the term “REST” causes some confusion in technical discussions.

This isn’t just pedantry on my part, well not quite. I’d recommend anyone involved in designing and architecting web sites read RESTful Web Services as well as Roy Fielding’s Architectural Styles and the Design of Network-based Software Architectures. But if you just want to get the general principles and don’t fancy wading through technical documents then you have to read How I Explained REST to My Wife hilariously written by Ryan Tomayko.

And remember, just because an API makes use of HTTP doesn’t make it RESTful. I’m looking at you twitter.

Invited to Join WaSP

I had a great time at SemanticCamp over the weekend which was not too much of a surprise. What was a surprise was getting back home to find out that I’ve been invited to join the Web Standards Project (WaSP) on the Education Task Force. I even have my own page.

Thanks for inviting me guys. Anyone who has had the misfortune of having me present during a discussion of the current state of web education knows it’s one of my favourite subjects. Hopefully I can make myself useful around the place and help with getting a few things done. More on this when I know more but in the meantime feel free to pester me endlessly if you have a particular axe to grind.

Example of the Yahoo Live Api

Yahoo! Live launched recently along with a nice RESTful API. I’ve spoken before about the beauty of REST being in lowering the barrier to hacking and when I wanted a quick feature for Live it was simplicity itself to put together.

A few friends are using it far too much it seems, Ben has 7.6 hours and Si has already clocked up 15 hours. But for the most part I keep missing their no-doubt highly entertaining antics. One thing that Live misses I feel is a favourite users or previously viewed channels list. Basically I want to see which of my friends who use the service are broadcasting right now. Something like:

Yahoo! Live Online

The API request we’re interested in is the /channel/PERMALINK method. This lets us get information about whether the user is broadcasting at the moment.

<code><?php
$api = 'http://api.live.yahoo.com/api/v1/channel';
$friends = array(
  'garethr',
  'benward',
  'sijobling'
);
$statuses = array();
foreach ($friends as $friend) { 
  $response = simplexml_load_file($api . '/' . $friend);
  $name = $response->name; 
  if ($response->broadcast) {
    $status = 'live';
  } else {
    $status = 'offline';
  }
  $statuses["$name"] = $status;
}
function displaylist($array) {
  $output = '';
  if (count($array) >= 0) {
    $output .= '<ul>';
    foreach ($array as $key => $value) {
      $output .= "<li class=\"$value\">";
      $output .= "<a href=\"http://live.yahoo.com/$key\">";
      $output .= "$key</a>";
      $output .= "<span>$value</span></li>";
    }
    $output .= '</ul>';
  }
  return $output;
}
echo displaylist($statuses);
?></code>

I’ll add a few more people to my list when I discover other people using the service. If you have an account leave a comment. I’ve added a touch of javascript as well so as to avoid having to reload the page manually. This way I can loiter on my little aggregator until someone I know starts broadcasting and head over to Live for whatever Si has been spending 15 hours doing.

Continuous Integration for Front End Developers

Most software developers, especially those with a grounding in Agile development methodologies, will probably be familiar with Continuous Integration

Continuous Integration is a software development practice where members of a team integrate their work frequently, usually each person integrates at least daily - leading to multiple integrations per day. Each integration is verified by an automated build (including test) to detect integration errors as quickly as possible.

The emphasis above is mine, purely as it’s at the heart of what I’m going to ramble on about. A little closer to home Ryan King just posted about a new site; inursite. The premise is simple; enter a few of your sites and inursite will visit them once a day and run a markup validation service over the page. You then get a feed of the pass or failure status. It’s simple but brilliant. For example, I have this very site added to the service. If I put some invalid markup in this post, tomorrow morning I’ll get an item in my feedreader telling me of my mistake. I’ll get that every day until I fix the problem.

This green/red (pass/fail) type approach to simple tests is what I find most powerful about continuous integration systems like Cruise Control. Ryan asked over on his site in one of the comments what I’d like to see, so lets see:

  • Has all the CSS been compressed using something like CSSTidy.
  • Has all the javascript been compressed using something like JSMin.
  • Does any Javascript pass the harsh taskmaster that is JSLint.
  • If my markup a little bloated? Maybe I could set a maximum size for the markup and get a fail is I go over that.
  • Ditto CSS file size.
  • Ditt Javascript.
  • Ditto images.
  • If pages have associated feeds, then validate them as well according to the relevant specification (probably RSS or Atom).
  • How many HTTP Requests does it take to load the whole page, including all the relevant assets. I’d like to be able to set a maximum number.
  • How many hosts are required to load the whole page? I’d like to be able to set a maximum number and get a fail if I go over that.
  • Is the page gzipped on the server.
  • And just to keep this topical, does the page have either the IE8 meta element or the associated HTTP header set to a particular value.

Lots of this is front-end best practice, some coming from the YAHOO! exceptional performance work. It’s something I’ve touched on before too. Can anyone else think of other things you’d like to see when you’re working away crafting markup and CSS? Once you have all these tests running you could display them in widgets, gadgets, twitter, firefox extensions, large displays, mobile devices, the works.

Now that sounds like an awful lot of stuff for one person (or even for one application) but I have something else in mind. If inursite allowed you to hook up external webservices which accept a URL as an argument, along with any service specific parameters, and return true or false then, in theory, anyone could add their own custom checks to it. This becomes particularly useful for larger teams than are likely to have internal quality tools already. On top of all that I’d probably pay for a service like this that let me run it on demand (rather than once per day) - or maybe even better, pay for a downloadable version (a.l.a. Mint) I can install locally.

As you can probably tell, I think the general idea of continuous integration for front end web developer is one for which time has come. It’s simply part of our discipline growing up and becoming more professional. Whether Ryan looks to extend his fantastic simple service in this direction or not I hope something will come along that does all this and more. I might even work on it myself - but then I always say that!

Simple deployment with SVN and Phing

Another approach to deploying web apps is to use Phing. Phing is at heart a PHP clone of Ant, another common build and deployment tool. The main advantage of using Phing, at least if you’re already using PHP, is close integration with other PHP specific tools (PHPDocumentor, PHPLint and PHPUnit to name a few) and ease of install.

Speaking to installation Phing has it’s own PEAR channel. I still think PEAR is great in so many different ways - it always makes me frown when I see people cussing at PEAR (especiallly the installer). You can install Phing as follows.

<code>pear channel-discover pear.phing.info
pear install phing/phing</code>

The Phing documentation is nothing if not comprehensive. Unfortunately, unless you are pretty familiar with Ant or you’re trying to do something complex (and willing to invest the time) the chances are you’ll be a little lost. More and simpler examples for common problems would be useful for those beginners.

I might publish a few little recipes down the line or even a full commented production recipe but for the moment lets start simple. The following build script is designed to be run on your remote web server and relies on a subversion repository (hopefully you’re using source control, if not that’s another post I’m afraid). It simply exports the specified repository to the specified export directory on the server. Note that you need to set your own SVN details and replace the capitalised properly values. The following should be saved as build.xml on your web server, outside the web root.

<code><?xml version="1.0"?>
<project name="build" default="main">

  <property name="exportdir"  value="WEB_ROOT" />
  <property name="svnpath" value="YOUR_SVNPATH" />
  <property name="username" value="YOUR_SVN_USERNAME" />
  <property name="password" value="YOUR_SVN_PASSWORD" />
  <property name="repo" value="YOUR_SVN_REPO" />

  <target name="main" depends="svnexport"/>

  <target name="svnexport">
    <svnexport
       svnpath="${svnpath}"
       username="${username}"
       password="${password}"
       nocache="true"
       repositoryurl="${repo}"
       todir="${exportdir}"/>
  </target>
</project></code>

Let’s break some of that down. Property definitions allow you to specify variables for use in your build script. In this example we only have one task specified so maybe we don’t need the extra abstraction but the moment we start reusing scripts or adding more tasks it’s a good idea.

<code><property name="exportdir"  value="./web" /></code>

The other major point of interest is the task itself. Here we make use of the properties we have already specified to run a subversion export. The svnexport task is build in to Phing.

<code><target name="svnexport">
  <svnexport
     svnpath="${svnpath}"
     username="${username}"
     password="${password}"
     nocache="true"
     repositoryurl="${repo}"
     todir="${exportdir}"/>
</target></code>

Also of note is the setting of a default task, main, as a property of the project element and specifying that the main task depends on another task, svnexport. Again, we could avoid that at this stage but the moment we add another few tasks then we’ll want more control over execution order.

Phing should be run from the directory containing the build script. You can run the command without any arguments, in which case the default task will be run (in our case main) or you can pass an argument to specify a specific task. For our simple build script the two following commands do the same thing:

<code>phing</code>

<code>phing svnexport</code>

Given the above build script simple runs a subversion export command you might be wondering what use it is. The answer is not much at this stage. You do get a simple build script which can be stored in your source control system and used by the whole team. The real advantage is where you might go from here. If everyone in your team deploys in the same way (ie. using the build script) then anyone can add extra tasks and everyone gets the benefit. Simple example might be generating code documentation, running Unit tests (and not running the export if the tests fail) and creating a zip file of the deployed source for backup purposes.

Build scripts can get complicated quickly, but if you start out small and add tasks as you need and understand them, you should be able to raise the quality of your application and avoid easy to make mistakes.

Questions, Pointers and Reality

Along with an awful lot of noise, the whole X-UA-COMPATIBLE IE8 issue is also bringing out some well rounded and thought through arguments from people I admire.

I still disagree with Jeremy Keith on the default issue but agree with everything else. Jeremy says:

Let me make it perfectly clear: I understand the need for version targeting. But the onus must be on the publisher to enable it.

At the moment it comes down to a sense of stubborn realism on my part. All the people who know about the issue and the need for the new header (that would be me, Jeremy, probably you and the whole web standards developer crowd) are probably also in a position to add it fairly easily. All those that don’t know about the header don’t have to know about it. Ever. I would prefer if this wasn’t the case but alas I think it might be.

Mike Davies has one of the most well argued points out their. Throwing into the pot the issue of content not served via a web server raises even more issues that make changing the default behaviour difficult. I think Mike sums this up pretty well:

Every other browser has either started from scratch from the ground up (Firefox and Opera), or created a browser after the browser-wars (Safari). As such, all three have benefited from not having to support Microsoft’s excess baggage. And Microsoft being dragged to a complete stop because of it. This is Microsoft’s browser-war victory biting them in the ass.

Whether we like it or not this issue is about Microsoft, and I (maybe naively) believe Microsoft would like nothing better than to get back up from the mat and innovate in the browser space. But they can’t because of the ball and chain.

Who hasn’t written at least some code that, in hindsight, turned into a horrible maintenance nightmare? You might dream of jumping in and rewriting it from scratch but if that code has already been shipped to a client then what is that client doing to do? Turning around and saying actually, what we gave you originally was pretty rubbish isn’t going to go down well - even when it’s the right thing to do.

Mike is right in that the IE team are actually going to be shipping two browsers. That has got to be a massive issue for them - certainly a bigger issue than me adding a new header to my site or a meta element to my pages. But if it lets the second of those browsers support CSS3, HTML5, XHTML, Canvas and anything else we dream of then I’m all for it. We all know the first of those browsers just won’t be up to the task.

One particular thorny problem I wasn’t aware of was issues surrounding accessibility. Bruce Lawson has some of the details but in short by locking a large number of sites into the ways of IE7 we essentially freeze the (poor) state of accessibility on the web. Patrick Lauke also raises a related issue in the comments regarding further alienating screen reader and assistive technology developers. These points for me are ones I want addressing by Microsoft and one’s without resolution which would make me change my mind on this whole issue of defaults.

So, the jury is still out in my mind. I hope it is in the minds of those working closer to the heart of this problem at Microsoft. Like Molly I’m glad this issue has been raised now, rather than simply revealed at launch. I just hope the reason for that was to get the sort of high quality feedback we’re seeing in some areas of the community in order to test the waters and come to a consensus.