106
SPEAKER‘S COMPANY LOGO REST in peace A handbook of software waste Alessandro Nadalin DNSEE 430

REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

Embed Size (px)

DESCRIPTION

A 20-minutes presentation I gave at the 2011 Jazoon conference in Zurich about RESTful architectures, REST antipatterns and how to implement scalability and adaptability in our systems.

Citation preview

Page 1: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

REST in peaceA handbook of software waste

Alessandro Nadalin

DNSEE

430

Page 2: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

2

AGENDA

> Vol. 1: REST in a nutshell

– Tenets

– Antipatterns

> WWW: a tremendous architecture

– Stateless

– Layered

– Cacheable

– Fault-tolerant

– Failure-prone

> Vol. 2: To the rescue

– HTTP cache

– ESI

– HATEOAS

> Vol. 3: REST is not a panacea

– SOAP

– Limited horizon

– Agile development

Page 3: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

Sorry for the ugly slide.

There will be others.Really sorry.

Page 4: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

REST in a nutshell:

1. Client <> Server

Page 5: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

REST in a nutshell:

2. Stateless

Page 6: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

3. Cacheable

REST in a nutshell:

Page 7: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

REST in a nutshell:

4. Layered system

Page 8: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

REST in a nutshell:

5. Uniform interface

Page 9: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

9

And obviously nobody had a clue

Page 10: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

10

ANTIPATTERNS

Page 11: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

1URIs

Page 12: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

"REST is about

cool URI design"

http://apple.com/users/1/licenses/4.json

Page 13: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

"REST is about

cool URI design"

http://apple.com/users/1/licenses/4.json

Page 14: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

http://apple.com/site/en_US/showUsers.jsp?uid=1&license=4

is OK too

Page 15: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

but

Page 16: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

cool URIs help youthink in term of resources

David Zuelke

Page 17: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

2URIs (bis)

Page 18: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

GET /users POST /users PUT /users/{id} DELETE /users/{id} ...

REST follows a URI schema

Page 19: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

GET /users POST /users PUT /users/{id} DELETE /users/{id} ...

REST follows a URI schema

Page 20: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

what if you change yourURL?

Page 21: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

Yeah, client is broken

Page 22: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

RESTful clients shouldbe driven by service'shypermedia controls

Roy Fielding : http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven

Page 23: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

HATEOAS

Page 24: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

3POST is cool

Page 25: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

said SOAP

Page 26: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

said SOAP

Page 27: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

loosing meaningful verbs at the protocol level

Page 28: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

loosing meaningful verbs at the protocol level

nothing cacheable by default

Page 29: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

loosing meaningful verbs at the protocol level

nothing cacheable by default

what about bookmarking?

Page 30: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

30

Have a break

Page 31: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

31

The WWW

Page 32: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

32

the largest data-exchange network on the planet

Page 33: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

33

And meanwhile, at Facebook...

12TB of new data every day(1 year ago)

500 million users

Page 34: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

34

via HTTP, baby!

Page 35: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

HTTP in a nutshell:

1. Client <> Server

Page 36: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

HTTP in a nutshell:

2. Stateless

Page 37: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

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

3. widespread cache spec

HTTP in a nutshell:

Page 38: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

HTTP in a nutshell:

4. Layered systemOrigin server

Reverse proxy

Great chinese (fire)wall

Company proxy

Lao Tze Song office's laptop

Page 39: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

HTTP in a nutshell:

5. it is the uniform interfacebetween clients and servers

Page 40: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

40

HTTP bleeds REST

Page 41: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

Vol.2Implementing all this goodness

Page 42: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

1.

caching & scalability

Page 43: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

Caching withExpiration

Page 44: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

HTTP/1.1 200 OKHost: www.example.comExpires: 0

Page 45: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

HTTP/1.1 200 OKHost: www.example.comExpires: 0

Page 46: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

HTTP/1.1 200 OKHost: www.example.comExpires: Tue, 31 Jan 2011 01:00 GMT

Page 47: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

HTTP/1.1 200 OKHost: www.example.comCache-Control: max-age=60, public

Page 48: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

HTTP/1.1 200 OKHost: www.example.comCache-Control: max-age=60, public

Page 49: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

HTTP/1.1 200 OKHost: www.example.comCache-Control: max-age=60, public

Cacheable for 60 seconds

Page 50: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

GET / HTTP/1.1Host: www.example.comCache-Control: max-age=60, public

Cacheable by both local and shared caches

Page 51: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

HTTP/1.1 200 OKHost: www.example.comCache-Control: stale-if-error=600, stale-while-revalidate=600

Page 52: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

HTTP/1.1 200 OKHost: www.example.comCache-Control: stale-if-error=600, stale-while-revalidate=600

fault-tolerant

Page 53: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

HTTP/1.1 200 OKHost: www.example.comCache-Control: stale-if-error=600, stale-while-revalidate=600

available during downtime

Page 54: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

HTTP/1.1 200 OKHost: www.example.comCache-Control: stale-if-error=600, stale-while-revalidate=600

available during revalidation

Page 55: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

Caching withValidation

Page 56: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

HTTP/1.1 200 OKHost: www.example.comEtag: 1234

Page 57: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

HTTP/1.1 200 OKHost: www.example.comEtag: 1234

an identifier for your response

Page 58: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

GET / HTTP/1.1Host: www.example.comIf-None-Match: 1234

the browsers asks you if it has been modified

Conditional requests

Page 59: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

HTTP/1.1 304 Not Modified

Page 60: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

Calculating an Etag is cheaper than generating a full MVC response

Page 61: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

but hey, you say

Page 62: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

HTTP's cache fails when dealing with really dynamic pages, because consumers will always have to hit the

origin server, although a part of the page would be cacheable ( header and footer, for example )

Page 63: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

Nope

Nope

Page 64: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

ESI was built for thathttp://www.w3.org/TR/esi-lang

Page 65: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

Edge Side Includes

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

Page 66: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

<esi:include src="http://jazoon.com/talks/1" />

Page 67: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

<esi:include src="http://jazoon.com/talks/1" />

Page 68: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

<esi:include src="http://jazoon.com/talks/1" />

Page 69: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

15 seconds cache

1 day cache

Page 70: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

<esi:include src='tweets.html' />

<esi:include src='footer.html' />

Page 71: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

and hey, Varnish is a reverse proxy implementing what you need of the ESI specification

take 2, pay for 1

Page 72: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

So what does HTTP cache is meant to solve?

Page 73: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

Less work

Page 74: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

because the hard work is delegated to the browser/proxy

http://www.flickr.com/photos/snakphotography/5004775320/sizes/o/in/photostream/

Page 75: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

evolve

Page 76: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

because cache is abstracted from the application

Page 77: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

loose coupling

Page 78: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

because caching is bound to the protocol, HTTP, not to your implementation ( Sf, RoR, Django )

Page 79: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

2.

adaptability & durability

Page 80: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

Hypermediaanother long-time friend

Page 81: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

Linksoutrageously semplifying

Page 82: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

<link rel="payment" href="/checkout" type="text/html" ... />

Page 83: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

<link rel="payment" href="/checkout" type="text/html" ... />

Page 84: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

<link rel="payment" href="/checkout" type="text/html" ... />

Page 85: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

<link rel="payment" href="/checkout" type="text/html" ... />

Page 86: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

HTTP/1.1 201 CreatedHost: www.example.comEtag: 1234X-Powered-By: php/5.3Location: /users/1

POST /usersHost: www.example.com

Page 87: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

HTTP/1.1 201 CreatedHost: www.example.comEtag: 1234X-Powered-By: php/5.3Location: /users/1

POST /usersHost: www.example.com

Page 88: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

HTTP/1.1 201 CreatedHost: www.example.comEtag: 1234X-Powered-By: php/5.3Location: /new-users-db/1

POST /usersHost: www.example.com

Page 89: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

HTTP/1.1 201 CreatedHost: www.example.comEtag: 1234X-Powered-By: php/5.3Location: /new-users-db/1

POST /usersHost: www.example.com

Page 90: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

consumers of your API are able to followthe changes of your design

Page 91: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

everything seems cool

But why REST?

Page 92: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

Pros

Performances

Page 93: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

Pros

Scalability

Page 94: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

Page 95: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

Pros

Durability

Page 96: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

"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

Page 97: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

Put a bit of REST

everywhere

Page 98: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

Rules of good design

Page 99: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

Use natives=

Eliminate waste

Page 100: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

The wheel!

HTTP - 1991~1997

REST - 2000

Page 101: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

Vol.3REST is not a panacea

Page 102: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

SOAPNo need to re-invent the wheel: if you need to do SOAP integration, SOAP

is the way.

If you have a completely functional SOAP service, no - apparent - need to rewrite it RESTful from scratch.

Page 103: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

AGILE

The last responsible moment conflicts with REST.

But quality enhance agility: REST is quality.

Page 104: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

LIMITED HORIZON

My blog won't ever be RESTful.

But incremental design, bare it in mind.

Page 105: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

Alessandro Nadalin odino.orgDNSEE @_odino_Rome github.com/odino

Page 106: REST in peace: a handbook of software waste @ Jazoon 2011 06-22-2011

SPEAKER‘S COMPANY

LOGO

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/

http://www.flickr.com/photos/rustyboxcars/2629631562/sizes/l/in/photostream/http://www.flickr.com/photos/ell-r-brown/4138727474/sizes/l/in/photostream/http://www.flickr.com/photos/noah123/5082076630/sizes/z/in/photostream/http://www.flickr.com/photos/jungle_boy/220181177/sizes/l/in/photostream/

http://www.flickr.com/photos/prettydaisies/872539081/sizes/l/in/photostream/http://www.flickr.com/photos/kaptainkobold/76256150/sizes/o/in/photostream/

http://www.flickr.com/photos/uomoincravatta/1438372865/sizes/z/in/photostream/