REST in peace @ Codemotion 2011

Post on 08-May-2015

3.783 views 2 download

description

Presentation at the 2011 Codemotion (formerly known as the italian JavaDay) about RESTful architectures and caching with Edge Side Includes specification.

Transcript of REST in peace @ Codemotion 2011

RESTin peace

Licensed under CC license

Rome, March 5th 2011

Licensed under CC licenseRome, March 5th 2011

Agenda

Rest in a nutshell

The uniform interface

Bad APIs

ESI + REST

ESI in a nutshell

Pros/Cons

Problems

Licensed under CC licenseRome, March 5th 2011

Sorry for the ugly slide.

There will be others.Really sorry.

Licensed under CC licenseRome, March 5th 2011

Let's go!

Licensed under CC licenseRome, March 5th 2011

Let's go back!

Licensed under CC licenseRome, March 5th 2011

2000Fielding's dissertation:

REpresentational

State

Transfer

http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm

Licensed under CC licenseRome, March 5th 2011

REST in a nutshell:

Licensed under CC licenseRome, March 5th 2011

REST in a nutshell:

1. Client <> Server

Licensed under CC licenseRome, March 5th 2011

REST in a nutshell:

2. Stateless

Licensed under CC licenseRome, March 5th 2011

Recover andfailoverparadise

Licensed under CC licenseRome, March 5th 2011

What about the user session?

Licensed under CC licenseRome, March 5th 2011

Must die

Licensed under CC licenseRome, March 5th 2011

What about the user cookies?

Licensed under CC licenseRome, March 5th 2011

Should die

Licensed under CC licenseRome, March 5th 2011

Wondering why?

Licensed under CC licenseRome, March 5th 2011

Wondering why?

Send a cookie via FTP.http://www.google.it/search?sourceid=chrome&client=ubuntu&channel=cs&ie=UTF-8&q=ftp+cookies

Andhttp://www.ics.uci.edu/~fielding/pubs/dissertation/evaluation.htm#sec_6_3_4_2

3. Cacheable Licensed under CC license

Rome, March 5th 2011

REST in a nutshell:

When dealing with safe methods,the response should be able to tell the client,

or whatever stands behind the request,how to cache it.

Licensed under CC licenseRome, March 5th 2011

REST in a nutshell:

Licensed under CC licenseRome, March 5th 2011

REST in a nutshell:

4. Layered system

Licensed under CC licenseRome, March 5th 2011

REST in a nutshell:

5. Uniform interface

Licensed under CC licenseRome, March 5th 2011

Uniform interfacehierarchic resource identification

HTTP verbs to perform operations

manipulation through representation

HATEOAS

Licensed under CC licenseRome, March 5th 2011

Richardson maturity model

hierarchic resource identification

HTTP verbs to perform operations

manipulation through representation

HATEOAS

Really well explained by Fowler: http://martinfowler.com/articles/richardsonMaturityModel.html#level0

Licensed under CC licenseRome, March 5th 2011

Richardson maturity model

hierarchic resource identification

HTTP verbs to perform operations

HATEOAS

mess

Licensed under CC licenseRome, March 5th 2011

Richardson maturity model

hierarchic resource identification

HTTP verbs to perform operations

HATEOAS

mess0.

Licensed under CC licenseRome, March 5th 2011

0Using HTTP

Licensed under CC licenseRome, March 5th 2011

Without giving a f***

Licensed under CC licenseRome, March 5th 2011

Richardson maturity model

hierarchic resource identification

HTTP verbs to perform operations

HATEOAS

mess0.1.

Licensed under CC licenseRome, March 5th 2011

1mytastyproduct.com/users

mytastyproduct.com/users/1/licenses/4

Licensed under CC licenseRome, March 5th 2011

Richardson maturity model

hierarchic resource identification

HTTP verbs to perform operations

HATEOAS

mess0.1.2.

Licensed under CC licenseRome, March 5th 2011

2

3.

Licensed under CC licenseRome, March 5th 2011

Richardson maturity model

hierarchic resource identification

HTTP verbs to perform operations

HATEOAS

mess0.1.2.

Licensed under CC licenseRome, March 5th 2011

3. GOD

http://www.slideshare.net/trilancer/why-hateoas-1547275

Licensed under CC licenseRome, March 5th 2011

Hyperlinks

Licensed under CC licenseRome, March 5th 2011

Hypermedia formats

http://amundsen.com/hypermedia/

Licensed under CC licenseRome, March 5th 2011

Single entry point

Licensed under CC licenseRome, March 5th 2011

Uniform interface is interesting.

Everyone seem to have its own RESTful "service".

But no one seem to entirely implement a uniform interface.

Licensed under CC licenseRome, March 5th 2011

Uniform interface is interesting.

Everyone seem to have its own RESTful "service".

But no one seem to entirely implement a uniform interface.

That means... ...?

Licensed under CC licenseRome, March 5th 2011

No RESTful

stuff

Licensed under CC licenseRome, March 5th 2011

But don't be too religious.

Licensed under CC licenseRome, March 5th 2011

But don't be too religious.Cookies stuff included.

REST gets raped everyday, get over it.

Licensed under CC licenseRome, March 5th 2011

Counterorder

Licensed under CC licenseRome, March 5th 2011

Let's be religious'bout that!

Licensed under CC licenseRome, March 5th 2011

Just for a couple minutes :)

Licensed under CC licenseRome, March 5th 2011

API #fail

Licensed under CC licenseRome, March 5th 2011

Licensed under CC licenseRome, March 5th 2011

flickr.com/people/{user-id}

Licensed under CC licenseRome, March 5th 2011

flickr.com/photos/{user-id}

flickr.com/photos/{user-id}

Licensed under CC licenseRome, March 5th 2011

flickr.com/users/{user-id}/photos/

Licensed under CC licenseRome, March 5th 2011

flickr.photos.delete

Licensed under CC licenseRome, March 5th 2011

wow, a delete!

Licensed under CC licenseRome, March 5th 2011

POST

Licensed under CC licenseRome, March 5th 2011

Is that even legal?

Licensed under CC licenseRome, March 5th 2011

Licensed under CC licenseRome, March 5th 2011

GET /api.twitter.com/1/users/show.format

Licensed under CC licenseRome, March 5th 2011

GET /api.twitter.com/1/users/show.format

GET /api.twitter.com/1/users/HTTP Accept header:

http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html

Licensed under CC licenseRome, March 5th 2011

GET /api.twitter.com/1/users/search.format?query...

Licensed under CC licenseRome, March 5th 2011

GET /api.twitter.com/1/users/search.format?query...

GET /api.twitter.com/1/users?name=jack

Licensed under CC licenseRome, March 5th 2011

Licensed under CC licenseRome, March 5th 2011

Only JSON responses

Licensed under CC licenseRome, March 5th 2011

JSON is evil

Licensed under CC licenseRome, March 5th 2011

{ "date": "2011-01-01", "stock": "100", "price": "12"}

Licensed under CC licenseRome, March 5th 2011

The business evolves

Licensed under CC licenseRome, March 5th 2011

{ "date": "2011-01-01", "stock": "100", "price": [ {"currency": "EUR", "amount": "12"}, {"currency": "USD", "amount": "10"} ]}

Credits: http://twitter.com/#!/odracci

Licensed under CC licenseRome, March 5th 2011

Yeah, client is broken

Licensed under CC licenseRome, March 5th 2011

No good

Licensed under CC licenseRome, March 5th 2011

BTW<xml...> <product...> <price currency="EUR">25</price> <price currency="USD">23</price> </product></xml>

Licensed under CC licenseRome, March 5th 2011

Well, getting back to...

Licensed under CC licenseRome, March 5th 2011

Licensed under CC licenseRome, March 5th 2011

Create a new class

http://<server>:[<port>]/class/<database>/<class-name>

Licensed under CC licenseRome, March 5th 2011

Response?

Licensed under CC licenseRome, March 5th 2011

HTTP/1.1 201 Created

Cache-Control: no-cache, no-store, max-age=0, must-revalidate

Pragma: no-cache

Date: Fri Feb 18 03:21:09 CET 2011

Content-Type: text/plain

Server: OrientDB Server v.0.9.24

Connection: Keep-Alive

Set-Cookie: OSESSIONID=OS12979956697985725150466358620636; Path=/; HttpOnly

CONTENT-LENGTH: 221

CAN I HAZ HATEOAZ? Licensed under CC license

Rome, March 5th 2011

Licensed under CC licenseRome, March 5th 2011

HTTP 201 Created

Location /bla bla bla bla...

http://en.wikipedia.org/wiki/HTTP_location

Licensed under CC licenseRome, March 5th 2011

I am really ashamed of havingbothered you for 78 slides

to say how to perform a GET

Licensed under CC licenseRome, March 5th 2011

ESIin peace

Rome, March 5th 2011

Licensed under CC licenseRome, March 5th 2011

Edge Side IncludesA de facto standard for bla bla bla...

Licensed under CC licenseRome, March 5th 2011

Edge Side IncludesA de facto standard for bla bla bla...

Server side includes ( not SSI! ) usually handled by the architecture's ESI processor.

http://www.w3.org/TR/esi-langhttp://www.w3.org/TR/edge-arch

Licensed under CC licenseRome, March 5th 2011

<esi:include src="http://codemotion.it/talks/1" />

Include

Licensed under CC licenseRome, March 5th 2011

<esi:try> <esi:attempt> <esi:comment text="The REST talk"/> <esi:include src="http://codemotion.it/talks/1" /> </esi:attempt>

Try/Catch

Licensed under CC licenseRome, March 5th 2011

<esi:try> <esi:attempt> <esi:comment text="The REST talk"/> <esi:include src="http://codemotion.it/talks/1" /> </esi:attempt> <esi:except> <esi:comment text="fallback"/> <p>epic fail</p> </esi:except> </esi:try>

Fallback

Licensed under CC licenseRome, March 5th 2011

Pitfalls

Licensed under CC licenseRome, March 5th 2011

PitfallsProcessor configuration

Licensed under CC licenseRome, March 5th 2011

PitfallsProcessor configuration

Implementation of fallbacks for handling errors

Licensed under CC licenseRome, March 5th 2011

PitfallsProcessor configuration

Implementation of fallbacks for handling errors

it relies on the processor, which gains importance, for creating any single response ( not really true :-) )

Licensed under CC licenseRome, March 5th 2011

Pros

Licensed under CC licenseRome, March 5th 2011

Pros

Performances

Licensed under CC license

Effective gateway cacheRome, March 5th 2011

Pros

Licensed under CC licenseRome, March 5th 2011

ProsScalability

Licensed under CC licenseRome, March 5th 2011

Which leads us to...

Licensed under CC licenseRome, March 5th 2011

REST+ESIin peace

Rome, March 5th 2011

Licensed under CC licenseRome, March 5th 2011

This is a response

Licensed under CC licenseRome, March 5th 2011

aggregating many resources

Licensed under CC licenseRome, March 5th 2011

So here's a resource.

Licensed under CC licenseRome, March 5th 2011

So here's a resource.

Or, better, its representation.

Licensed under CC licenseRome, March 5th 2011

Five minutes cache

2 days cache

Licensed under CC licenseRome, March 5th 2011

Let's write our own caching system

Licensed under CC licenseRome, March 5th 2011

because we need to cache different resources with different expiring intervals

odino@odino-phenom:~$ ab -n 1000 -c 10 http://127.0.0.1/tmp/esi.phpThis is ApacheBench, Version 2.3 <$Revision: 655654 $>Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 127.0.0.1 (be patient)Completed 100 requestsCompleted 200 requestsCompleted 300 requestsCompleted 400 requests

Licensed under CC licenseRome, March 5th 2011

Hell no!

Licensed under CC licenseRome, March 5th 2011

USE ESIand HTTP

cache

Licensed under CC licenseRome, March 5th 2011

Understanding the web cache

http://www.mnot.net/cache_docs/#WORK

HTTP cache

http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html

Licensed under CC licenseRome, March 5th 2011

Without a single LoC

Licensed under CC licenseRome, March 5th 2011

ehm...

Licensed under CC licenseRome, March 5th 2011

With a few LoCs,

gotta admit

Licensed under CC licenseRome, March 5th 2011

TheArchitecture

Application

Licensed under CC licenseRome, March 5th 2011

Database

Client

Reverse proxy / ESI processor

Licensed under CC licenseRome, March 5th 2011

No problems, uh?

Licensed under CC licenseRome, March 5th 2011

Hell no!

Licensed under CC licenseRome, March 5th 2011

1. Complexity

Licensed under CC licenseRome, March 5th 2011

1. Complexity

Resolved by your needs

Licensed under CC licenseRome, March 5th 2011

2. Caching

Licensed under CC licenseRome, March 5th 2011

2. Caching

Resolved by the gateway cacheaka your reverse proxy

aka, most of the time, Varnish

Licensed under CC licenseRome, March 5th 2011

You know Varnish, don't you?

Licensed under CC licenseRome, March 5th 2011

Without varnishConcurrency Level: 10Time taken for tests: 1.467 secondsComplete requests: 1000Failed requests: 0Write errors: 0Total transferred: 5476471 bytesHTML transferred: 5285280 bytesRequests per second: 681.69 [#/sec] (mean)Time per request: 14.670 [ms] (mean)Time per request: 1.467 [ms] (mean, across all concurrent requests)Transfer rate: 3645.73 [Kbytes/sec] received

Licensed under CC licenseRome, March 5th 2011

With varnishConcurrency Level: 10Time taken for tests: 0.179 secondsComplete requests: 1000Failed requests: 0Write errors: 0Total transferred: 5479938 bytesHTML transferred: 5288556 bytesRequests per second: 5587.65 [#/sec] (mean)Time per request: 1.790 [ms] (mean)Time per request: 0.179 [ms] (mean, across all concurrent requests)Transfer rate: 29902.34 [Kbytes/sec] received

Licensed under CC licenseRome, March 5th 2011

AWESOME

huh?

Licensed under CC licenseRome, March 5th 2011

NO.

Licensed under CC licenseRome, March 5th 2011

Where's my HATEOAS, again?

Licensed under CC licenseRome, March 5th 2011

<esi:environment> <esi:request_header name="Accept" value="text/vnd.odino.xhtml"/></esi:environment>

Defining a requestheader in ESI

Licensed under CC licenseRome, March 5th 2011

<esi:environment> <esi:request_header name="Accept" value="text/vnd.odino.xhtml"/></esi:environment>

Defining a requestheader in ESI

Content Negotiation

Licensed under CC licenseRome, March 5th 2011

Awful support

Licensed under CC licenseRome, March 5th 2011

Application

Reverse proxy

Client

?

Licensed under CC licenseRome, March 5th 2011

Application

Reverse proxy

Client

ESI processor

Licensed under CC licenseRome, March 5th 2011

Some freaking crazy people built a webserver

Licensed under CC licenseRome, March 5th 2011

in PHP

Licensed under CC licenseRome, March 5th 2011

with the RAD framework

Symfony2

http://symfony-reloaded.org/

https://github.com/pminnieur/ServerBundle

Licensed under CC licenseRome, March 5th 2011

That means you should be able to write your own reverse proxy acting as an ESI processor.

I mean, if they were able to write a webserver...

Licensed under CC licenseRome, March 5th 2011

in PHP

Licensed under CC licenseRome, March 5th 2011

you have no excuses

Licensed under CC licenseRome, March 5th 2011

But please

Licensed under CC licenseRome, March 5th 2011

Make it support all the ESI stuff

Licensed under CC licenseRome, March 5th 2011

Not like Varnish

http://www.varnish-cache.org/trac/wiki/ESIfeatures

Licensed under CC licenseRome, March 5th 2011

Extendedcontent

negotiation

Licensed under CC licenseRome, March 5th 2011

text/vnd.xhtml+xml;profile=esi

Chapter 8: http://www.rfc-editor.org/rfc/rfc3236.txt

Licensed under CC licenseRome, March 5th 2011

text/vnd.xhtml+xml;profile=esi

<head> ....</head><body> <esi ... /></body>

Response to the proc

Licensed under CC licenseRome, March 5th 2011

Profile is used because the browserwon't render such this kind of formats:

Licensed under CC licenseRome, March 5th 2011

text/vnd.xhesiml+xml

Licensed under CC licenseRome, March 5th 2011

text/vnd.xhesiml+xml

<div> ....</div><span> <esi ... /></span>

Response for fragments

Licensed under CC licenseRome, March 5th 2011

Application

Reverse proxy

Client

ESI processor

Supportingall the ESIspecificationhttp://www.w3.org/TR/esi-lang

Licensed under CC licenseRome, March 5th 2011

Overhead?

Licensed under CC licenseRome, March 5th 2011

Is that a problem?

Licensed under CC licenseRome, March 5th 2011

Application

Reverse proxy

Client

ESI processor

Supportingall the ESIspecificationhttp://www.w3.org/TR/esi-lang

Licensed under CC licenseRome, March 5th 2011

Varnish is therefor a reason

Licensed under CC licenseRome, March 5th 2011

Because at that

Licensed under CC licenseRome, March 5th 2011

Varnish ROCKS!

Licensed under CC licenseRome, March 5th 2011

Ready to include a resource with our custom hypermedia

format

<esi:environment> <esi:request_header name="Accept" value="text/vnd.blablabla"/></esi:environment>

Licensed under CC licenseRome, March 5th 2011

But don't screw everything forgetting the remaining parts of HATEOAS, likehypermedia relations.http://www.slideshare.net/adorepump/hateoas-the-confusing-bit-from-resthttp://tech.groups.yahoo.com/group/rest-discuss/message/17011

Licensed under CC licenseRome, March 5th 2011

So, with a

Licensed under CC licenseRome, March 5th 2011

Layered

Licensed under CC licenseRome, March 5th 2011

Cacheable

Licensed under CC licenseRome, March 5th 2011

Stateless

Licensed under CC licenseRome, March 5th 2011

Driven by

Licensed under CC licenseRome, March 5th 2011

Uniform interface

Licensed under CC licenseRome, March 5th 2011

andhypermedia

Licensed under CC licenseRome, March 5th 2011

architecture

Licensed under CC licenseRome, March 5th 2011

Oh dear

Licensed under CC licenseRome, March 5th 2011

Richardsonmaturity

modellevel 3

Licensed under CC licenseRome, March 5th 2011

Again...

Licensed under CC licenseRome, March 5th 2011

Pros

Performances

Licensed under CC licenseRome, March 5th 2011

ProsScalability

Licensed under CC licenseRome, March 5th 2011

Pros

Durability

Licensed under CC licenseRome, March 5th 2011

Where to RESTin peace

Rome, March 5th 2011

Licensed under CC licenseRome, March 5th 2011

anywebservice

Licensed under CC licenseRome, March 5th 2011

machineto

machine

Licensed under CC licenseRome, March 5th 2011

Be the next AtomPub

http://bitworking.org/projects/atom/rfc5023.html

Licensed under CC licenseRome, March 5th 2011

Actually...

Licensed under CC licenseRome, March 5th 2011

Licensed under CC licenseRome, March 5th 2011

"REST is software design on the scale of decades: every detail is intended to promote software longevity and independent evolution. Many of the constraints are directly

opposed to short-term efficiency. Unfortunately, people are fairly good at short-term design, and usually awful at long-term design. "

Roy Fielding

Licensed under CC licenseRome, March 5th 2011

Put a bit of REST

everywhere

Licensed under CC licenseRome, March 5th 2011

http://articles.sfgate.com/2011-02-20/opinion/28613184_1_news-network-cable-and-satellite-website

http://tech.groups.yahoo.com/group/rest-discuss/message/17370

+2.500%traffic

Licensed under CC licenseRome, March 5th 2011

Rules of good design

Licensed under CC licenseRome, March 5th 2011

No need to be religious

Licensed under CC licenseRome, March 5th 2011

This talk sucksin peace

Rome, March 5th 2011

Licensed under CC licenseRome, March 5th 2011

1

Licensed under CC licenseRome, March 5th 2011

Agile developmentvs

REST

Licensed under CC licenseRome, March 5th 2011

Agile developmentvs

REST

mmmmmmmmmmmm................

http://www.odino.org/288/restful-and-agile-love-hate-love

Licensed under CC licenseRome, March 5th 2011

2

Licensed under CC licenseRome, March 5th 2011

Browserssuck

Licensed under CC licenseRome, March 5th 2011

HTTP authenticationhttp://www.odino.org/238/mockups-of-web-authentication-the-rest-rescue

Licensed under CC licenseRome, March 5th 2011

3

Licensed under CC licenseRome, March 5th 2011

HTML5

Licensed under CC licenseRome, March 5th 2011

Everybody loves it

Licensed under CC licenseRome, March 5th 2011

I HATEHTML5

Licensed under CC licenseRome, March 5th 2011

Original specification:

"support for PUT and DELETE verbs"

Licensed under CC licenseRome, March 5th 2011

People went insane

Licensed under CC licenseRome, March 5th 2011

Current status?

Licensed under CC licenseRome, March 5th 2011

Removed

Licensed under CC licenseRome, March 5th 2011

There are nouse cases

Licensed under CC licenseRome, March 5th 2011

They said

Licensed under CC licenseRome, March 5th 2011

http://www.w3.org/TR/2010/WD-html5-diff-20101019/#changes-2010-06-24

Licensed under CC licenseRome, March 5th 2011

Then people got mad

Licensed under CC licenseRome, March 5th 2011

A disclaimerin peace

Rome, March 5th 2011

Licensed under CC licenseRome, March 5th 2011

JSONdoes not suck. At all.

http://www.slideshare.net/Wombert/xml-versus-the-new-kids-on-the-block-phpbnl11-20110129

Licensed under CC licenseRome, March 5th 2011

Varnishdoes not suck. At all.

Licensed under CC licenseRome, March 5th 2011

HTML5does not suck. At all.

http://www.html5rocks.com/

Licensed under CC licenseRome, March 5th 2011

OrientDBrocks

Ask Luca Garulli, he might be in this room

http://www.orientechnologies.com/

Licensed under CC licenseRome, March 5th 2011

Everything is a tradeoff

Licensed under CC licenseRome, March 5th 2011

Hints?

Licensed under CC licenseRome, March 5th 2011

David Zuelkeknows best

Licensed under CC licenseRome, March 5th 2011

Design HTTP interfacesand RESTful webservices

http://www.slideshare.net/Wombert/designing-http-interfaces-and-restful-web-services-phpbnl11-20110128

Licensed under CC licenseRome, March 5th 2011

Othersknow best

Licensed under CC licenseRome, March 5th 2011

300 RESTful boring slides :)http://www.slideshare.net/guilhermecaelum/rest-in-practice

REST as the DBMS of the webhttp://www.slideshare.net/dnene/rest-representational-state-transfer-explained

Licensed under CC licenseRome, March 5th 2011

amazon.it

Thanks!

Alessandro Nadalinodino.org

Licensed under CC licenseRome, March 5th 2011

@_odino_

#codemotion

12 - 14 May, Verona

Creditshttp://www.flickr.com/photos/larachris/16564077/sizes/o/in/photostream/

http://www.flickr.com/photos/ashatenbroeke/4367373081/sizes/z/in/photostream/http://www.flickr.com/photos/yourdon/3140270189/sizes/l/in/photostream/http://www.flickr.com/photos/jox1989/4964706072/sizes/l/in/photostream/http://www.flickr.com/photos/brainfg/168506259/sizes/o/in/photostream/

http://www.flickr.com/photos/norte_it/3897091546/sizes/o/in/photostream/http://www.zdnet.com/blog/service-oriented/soap-versus-rest-a-matter-of-style/3568

http://www.flickr.com/photos/turtlemom_nancy/2046347762/sizes/l/in/photostream/http://www.flickr.com/photos/juanpg/3333385784/sizes/z/in/photostream/http://www.flickr.com/photos/congvo/301678287/sizes/l/in/photostream/

http://www.flickr.com/photos/ihasb33r/2573196546/sizes/z/in/photostream/http://www.flickr.com/photos/martin_heigan/4544138976/sizes/o/in/photostream/

http://www.flickr.com/photos/cknara/4195099999/sizes/o/in/photostream/http://www.flickr.com/photos/1080p/3076529265/sizes/l/in/photostream/

http://www.flickr.com/photos/adamrice/280300202/sizes/l/in/photostream/http://www.flickr.com/photos/tomer_a/541411897/sizes/o/in/photostream/http://www.flickr.com/photos/subpra/4514008262/sizes/l/in/photostream/

http://www.flickr.com/photos/lippincott/2539720043/sizes/l/in/photostream/http://www.flickr.com/photos/rawryder/5086090931/sizes/l/in/photostream/http://www.flickr.com/photos/robboudon/5312731161/sizes/l/in/photostream/

http://www.flickr.com/photos/bc-burnslibrary/4158243488/sizes/o/in/photostream/http://www.flickr.com/photos/13606325@N08/2416993706/sizes/o/in/photostream/

http://www.flickr.com/photos/neothezion/5135841069/sizes/l/in/photostream/http://www.flickr.com/photos/planetschwa/2494067809/http://www.flickr.com/photos/thomasthomas/258931782/