rest in peace @ codemotion 2011
DESCRIPTION
Presentation at the 2011 Codemotion (formerly known as the italian JavaDay) about RESTful architectures and caching with Edge Side Includes specification.TRANSCRIPT
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.
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
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
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
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
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
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/