SlideShare a Scribd company logo
1 of 227
+1
                                                       +1
            +1
                       +1
      +1                               +1
                                 +1
 +1              +1                               +1
       +1
                                  +1
                      +1
+1                                               +1
            +1               +1
                                            +1
      +1
                      +1
       +1                   +1
                 +1                    +1
1
Jon Crosby
http://joncrosby.me
Engine Yard Solo
      “The platform for
on-demand management of your
   Ruby on Rails application
        in the cloud.”
We’re Hiring
CloudKit
Open Web
 JSON
Appliance
Open Web
 JSON
Appliance
RESTful Collections
        of
 JSON Documents
CouchDB

Persevere
Ruby
$ gem install cloudkit
WayOfThinking.new
WayOfThinking.web
2009
if (developer.building_web_framework?) {
  MVCAbstraction.new
}
Rails 3
Rails 3 => API
framework = {
  :orm => AR
  :dispatcher => AD}.merge(
    :orm => YourORM)
framework = {
  :orm => AR
  :dispatcher => AD}.merge(
    :orm => YourORM)
framework = {
  :orm => AR
  :dispatcher => AD}.merge(
    :orm => YourORM)
! MVC
! MVC “in the back?”
RESTful Application Architectures
RADAR




Dave Thomas
http://pragdave.pragprog.com/pragdave/2007/03/the_radar_archi.html
Resource Composition in the Browser




                       A.S.
             Focus
Resource Composition in the Browser




                       A.S.
             Focus
Resource Composition in the Browser




                       A.S.
             Focus
Cappuccino




http://280slides.com
Sproutcore




http://sproutcore.com
Desktop / Mobile Apps
ESI

         Caching Layer
                          REST
          Fragment A     Service
Client

                          REST
          Fragment B
                         Service
jQueryUI

 Dojo

MooTools
WayOfThinking.web
Rack
The Web
HTTP
Intermediaries



HTTP
Intermediaries   App



HTTP
Intermediaries   App



HTTP
Intermediaries   Rack



HTTP
HTTP
Intermediaries



HTTP
Middleware



HTTP
Middleware   App



HTTP
Rack is the Web
Constraints
Constraints => Interface
Constraints => Interface => SPEC
CloudKit
REST
Roy Fielding


Architectural Styles and the
Design of Network-based Software Architectures


http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm
Build An App
config.ru
require ‘cloudkit’
expose :todos, :profiles
Done
$ rackup config.ru
$ curl -i http://localhost:9292/cloudkit-meta
$ curl -i http://localhost:9292/cloudkit-meta
HTTP/1.1 200 OK
ETag: quot;5b6f484abf2d95cec3ea8867d1754418quot;
Cache-Control: proxy-revalidate
Content-Type: application/json
Content-Length: 33

{quot;urisquot;:[quot;/todosquot;,quot;/profilesquot;]}
$ curl -i -XOPTIONS http://localhost:9292/todos
$ curl -i -XOPTIONS http://localhost:9292/todos
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 0
Allow: GET, HEAD, POST, OPTIONS
$ curl -i http://localhost:9292/todos
$ curl -i http://localhost:9292/todos
HTTP/1.1 200 OK
ETag: quot;df392c5664e6ecd64b83210fb925f6c8quot;
Link: <http://localhost:9292/todos/_resolved>; 
rel=quot;http://joncrosby.me/cloudkit/1.0/rel/resolvedquot;
Cache-Control: proxy-revalidate
Content-Type: application/json
Content-Length: 32

{quot;urisquot;:[],quot;totalquot;:0,quot;offsetquot;:0}
$ curl -i http://localhost:9292/todos
HTTP/1.1 200 OK
ETag: quot;df392c5664e6ecd64b83210fb925f6c8quot;
Link: <http://localhost:9292/todos/_resolved>; 
rel=quot;http://joncrosby.me/cloudkit/1.0/rel/resolvedquot;
Cache-Control: proxy-revalidate
Content-Type: application/json
Content-Length: 32

{quot;urisquot;:[],quot;totalquot;:0,quot;offsetquot;:0}
$ curl -i http://localhost:9292/todos
HTTP/1.1 200 OK
ETag: quot;df392c5664e6ecd64b83210fb925f6c8quot;
Link: <http://localhost:9292/todos/_resolved>; 
rel=quot;http://joncrosby.me/cloudkit/1.0/rel/resolvedquot;
Cache-Control: proxy-revalidate
Content-Type: application/json
Content-Length: 32

{quot;urisquot;:[],quot;totalquot;:0,quot;offsetquot;:0}
$ curl -i http://localhost:9292/todos
HTTP/1.1 200 OK
ETag: quot;df392c5664e6ecd64b83210fb925f6c8quot;
Link: <http://localhost:9292/todos/_resolved>; 
rel=quot;http://joncrosby.me/cloudkit/1.0/rel/resolvedquot;
Cache-Control: proxy-revalidate
Content-Type: application/json
Content-Length: 32

{quot;urisquot;:[],quot;totalquot;:0,quot;offsetquot;:0}
Link Relations and HTTP Header Linking

      IETF Draft by Mark Nottingham



http://tools.ietf.org/html/draft-nottingham-http-link-header-04
Hypermedia
          as the
Engine of Application State
                   -- Fielding
Connectedness
        -- Richardson, Ruby
$ curl -i -XPOST -d'{quot;titlequot;:quot;fooquot;}' 
    http://localhost:9292/todos
$ curl -i -XPOST -d'{quot;titlequot;:quot;fooquot;}' 
http://localhost:9292/todos
HTTP/1.1 201 Created
Cache-Control: no-cache
Content-Type: application/json
Content-Length: 159

{
    quot;okquot;:true,
    quot;uriquot;:quot;/todos/9216df80-0c7b-012c-af2e-0023dfa0a208quot;,
    quot;etagquot;:quot;9216dde0-0c7b-012c-af2e-0023dfa0a208quot;,
    quot;last_modifiedquot;:quot;Thu, 16 Apr 2009 06:13:04 GMTquot;
}
Read-optimized
HTTP-Oriented Storage
Metadata

   +

Document
URI, ETag, Last-Modified, etc.

             +

         Document
SQL
ORM
Tokyo Cabinet
Tokyo Cabinet Tables
todos[“random_id”] = {
  “uri” => “/todos/abc”,
  “etag” => “9216dde0-0c7b-012c”,
  “last_modified” => “Thu, 16 Apr 2009 06:13:04 GMT”,
  “remote_user” => “http://joncrosby.me”,
  “json” => “{”title”:”foo”}”,
  ...
}
Rufus::Tokyo

record = store.query { |q|
  q.add_condition(“uri”, :eql, “/todos/abc”)
}
Schema-free
*
Schema-free
HTTP and JSON
are the Schema
$ curl -i -XPUT -d'{quot;titlequot;:quot;barquot;}' 
 http://localhost:9292/todos/abc
$ curl -i -XPUT -d'{quot;titlequot;:quot;barquot;}' 
http://localhost:9292/todos/abc
HTTP/1.1 201 Created
Cache-Control: no-cache
Content-Type: application/json
Content-Length: 126

{
    quot;okquot;:true,
    quot;uriquot;:quot;/todos/abcquot;,
    quot;etagquot;:quot;f4538ca0-0c7b-012c-af2e-0023dfa0a208quot;,
    quot;last_modifiedquot;:quot;Thu, 16 Apr 2009 06:15:49 GMTquot;
}
$ curl -i -XOPTIONS http://localhost:9292/todos/abc
$ curl -i -XOPTIONS http://localhost:9292/todos/abc
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 0
Allow: GET, HEAD, PUT, DELETE, OPTIONS
$ curl -i http://localhost:9292/todos/abc
$ curl -i http://localhost:9292/todos/abc
HTTP/1.1 200 OK
Last-Modified: Thu, 16 Apr 2009 06:15:49 GMT
ETag: quot;f4538ca0-0c7b-012c-af2e-0023dfa0a208quot;
Link: <http://localhost:9292/todos/abc/versions>; 
rel=quot;http://joncrosby.me/cloudkit/1.0/rel/versionsquot;
Cache-Control: proxy-revalidate
Content-Type: application/json
Content-Length: 15

{quot;titlequot;:quot;barquot;}
$ curl -i http://localhost:9292/todos/abc
HTTP/1.1 200 OK
Last-Modified: Thu, 16 Apr 2009 06:15:49 GMT
ETag: quot;f4538ca0-0c7b-012c-af2e-0023dfa0a208quot;
Link: <http://localhost:9292/todos/abc/versions>; 
rel=quot;http://joncrosby.me/cloudkit/1.0/rel/versionsquot;
Cache-Control: proxy-revalidate
Content-Type: application/json
Content-Length: 15

{quot;titlequot;:quot;barquot;}
$ curl -i http://localhost:9292/todos/abc
HTTP/1.1 200 OK
Last-Modified: Thu, 16 Apr 2009 06:15:49 GMT
ETag: quot;f4538ca0-0c7b-012c-af2e-0023dfa0a208quot;
Link: <http://localhost:9292/todos/abc/versions>; 
rel=quot;http://joncrosby.me/cloudkit/1.0/rel/versionsquot;
Cache-Control: proxy-revalidate
Content-Type: application/json
Content-Length: 15

{quot;titlequot;:quot;barquot;}
$ curl -i http://localhost:9292/todos/abc
HTTP/1.1 200 OK
Last-Modified: Thu, 16 Apr 2009 06:15:49 GMT
ETag: quot;f4538ca0-0c7b-012c-af2e-0023dfa0a208quot;
Link: <http://localhost:9292/todos/abc/versions>; 
rel=quot;http://joncrosby.me/cloudkit/1.0/rel/versionsquot;
Cache-Control: proxy-revalidate
Content-Type: application/json
Content-Length: 15

{quot;titlequot;:quot;barquot;}
Auto-versioning
/:collection
/:collection/:uuid
/:collection/:uuid/versions
/:collection/:uuid/versions/:etag
/:collection
/:collection/:uuid
/:collection/:uuid/versions
/:collection/:uuid/versions/:etag
/:collection
/:collection/:uuid
/:collection/:uuid/versions
/:collection/:uuid/versions/:etag
/:collection
/:collection/:uuid
/:collection/:uuid/versions
/:collection/:uuid/versions/:etag
/:collection
/:collection/:uuid
/:collection/:uuid/versions
/:collection/:uuid/versions/:etag
$ curl -i http://localhost:9292/todos
$ curl -i http://localhost:9292/todos
HTTP/1.1 200 OK
Last-Modified: Thu, 16 Apr 2009 06:15:49 GMT
ETag: quot;0aca58964aa2e15a9365d72dd4c43472quot;
Link: <http://localhost:9292/todos/_resolved>; 
rel=quot;http://joncrosby.me/cloudkit/1.0/rel/resolvedquot;
Cache-Control: proxy-revalidate
Content-Type: application/json
Content-Length: 94

{
    quot;urisquot;:[
       quot;/todos/abcquot;,
       quot;/todos/9216df80-0c7b-012c-af2e-0023dfa0a208quot;
    ],
    quot;totalquot;:2,
    quot;offsetquot;:0
}
Lost Update Problem:
Lost Update Problem: Solved
2 Users
2 Users
2 Browsers
2 Users
2 Browsers
1 Document
2 Users
2 Browsers
1 Document

Fight!
2 Users
2 Browsers
1 Document

Hand Wave!
$ curl -i -XPUT -d'{quot;titlequot;:quot;bazquot;}' 
 http://localhost:9292/todos/abc
$ curl -i -XPUT -d'{quot;titlequot;:quot;bazquot;}' 
http://localhost:9292/todos/abc
HTTP/1.1 400 Bad Request
Cache-Control: no-cache
Content-Type: application/json
Content-Length: 25

{quot;errorquot;:quot;etag requiredquot;}
$ curl -i -XPUT 
-H'If-Match:f4538ca0-0c7b-012c-af2e-0023dfa0a208' 
-d'{quot;titlequot;:quot;bazquot;}' 
http://localhost:9292/todos/abc
$ curl -i -XPUT 
-H'If-Match:f4538ca0-0c7b-012c-af2e-0023dfa0a208' 
-d'{quot;titlequot;:quot;bazquot;}' 
http://localhost:9292/todos/abc
HTTP/1.1 200 OK
Cache-Control: no-cache
Content-Type: application/json
Content-Length: 126

{
    quot;okquot;:true,
    quot;uriquot;:quot;/todos/abcquot;,
    quot;etagquot;:quot;55286040-0c7d-012c-af2e-0023dfa0a208quot;,
    quot;last_modifiedquot;:quot;Thu, 16 Apr 2009 06:25:41 GMTquot;
}
$ curl -i -XPUT 
-H'If-Match:f4538ca0-0c7b-012c-af2e-0023dfa0a208' 
-d'{quot;titlequot;:quot;boxquot;}' 
http://localhost:9292/todos/abc
$ curl -i -XPUT 
-H'If-Match:f4538ca0-0c7b-012c-af2e-0023dfa0a208' 
-d'{quot;titlequot;:quot;boxquot;}' 
http://localhost:9292/todos/abc
HTTP/1.1 412 Precondition Failed
Cache-Control: no-cache
Content-Type: application/json
Content-Length: 31

{quot;errorquot;:quot;precondition failedquot;}
$ curl -i http://localhost:9292/todos/abc/versions
$ curl -i http://localhost:9292/todos/abc/versions
HTTP/1.1 200 OK
Last-Modified: Thu, 16 Apr 2009 06:25:41 GMT
ETag: quot;f7aae4894429a39c7c3fe0c8ea9aa00equot;
Link: <http://localhost:9292/todos/abc/versions/_resolved>;
rel=quot;http://joncrosby.me/cloudkit/1.0/rel/resolvedquot;
Cache-Control: proxy-revalidate
Content-Type: application/json
Content-Length: 109

{
    quot;urisquot;:[
       quot;/todos/abcquot;,
       quot;/todos/abc/versions/f4538ca0-0c7b-012caf2e-0023dfa0a208quot;
    ],
    quot;totalquot;:2,
    quot;offsetquot;:0
}
$ curl -i http://localhost:9292/todos/abc/versions
HTTP/1.1 200 OK
Last-Modified: Thu, 16 Apr 2009 06:25:41 GMT
ETag: quot;f7aae4894429a39c7c3fe0c8ea9aa00equot;
Link: <http://localhost:9292/todos/abc/versions/_resolved>;
rel=quot;http://joncrosby.me/cloudkit/1.0/rel/resolvedquot;
Cache-Control: proxy-revalidate
Content-Type: application/json
Content-Length: 109

{
    quot;urisquot;:[
       quot;/todos/abcquot;,
       quot;/todos/abc/versions/f4538ca0-0c7b-012caf2e-0023dfa0a208quot;
    ],
    quot;totalquot;:2,
    quot;offsetquot;:0
}
Why _resolved?
O(n)
1000 documents = 1001 GETs
:-(
Time to rewrite in Scala?
$ curl -i http://localhost:9292/todos/abc/versions/_resolved
$ curl -i http://localhost:9292/todos/abc/versions/_resolved
HTTP/1.1 200 OK
Last-Modified: Thu, 16 Apr 2009 06:25:41 GMT
ETag: quot;ea2238f8f2da37b70f3d2f09464f166equot;
Link: <http://localhost:9292/todos/abc/versions>; rel=quot;indexquot;
Cache-Control: proxy-revalidate
Content-Type: application/json
Content-Length: 384

{
    quot;documentsquot;:[
       {
          quot;etagquot;:quot;55286040-0c7d-012c-af2e-0023dfa0a208quot;,
          quot;uriquot;:quot;/todos/abcquot;,
          quot;last_modifiedquot;:quot;Thu, 16 Apr 2009 06:25:41 GMTquot;,
          quot;documentquot;:quot;{quot;titlequot;:quot;bazquot;}quot;
       },
       {
          quot;etagquot;:quot;f4538ca0-0c7b-012c-af2e-0023dfa0a208quot;,
          quot;uriquot;:quot;/todos/abc/versions/f4538ca0-0c7b-012c-af2e-0023dfa0a208quot;,
          quot;last_modifiedquot;:quot;Thu, 16 Apr 2009 06:15:49 GMTquot;,
          quot;documentquot;:quot;{quot;titlequot;:quot;barquot;}quot;
       }
    ],
    quot;totalquot;:2,
    quot;offsetquot;:0
}
$ curl -i http://localhost:9292/todos/abc/versions/_resolved
HTTP/1.1 200 OK
Last-Modified: Thu, 16 Apr 2009 06:25:41 GMT
ETag: quot;ea2238f8f2da37b70f3d2f09464f166equot;
Link: <http://localhost:9292/todos/abc/versions>; rel=quot;indexquot;
Cache-Control: proxy-revalidate
Content-Type: application/json
Content-Length: 384

{
    quot;documentsquot;:[
       {
          quot;etagquot;:quot;55286040-0c7d-012c-af2e-0023dfa0a208quot;,
          quot;uriquot;:quot;/todos/abcquot;,
          quot;last_modifiedquot;:quot;Thu, 16 Apr 2009 06:25:41 GMTquot;,
          quot;documentquot;:quot;{quot;titlequot;:quot;bazquot;}quot;
       },
       {
          quot;etagquot;:quot;f4538ca0-0c7b-012c-af2e-0023dfa0a208quot;,
          quot;uriquot;:quot;/todos/abc/versions/f4538ca0-0c7b-012c-af2e-0023dfa0a208quot;,
          quot;last_modifiedquot;:quot;Thu, 16 Apr 2009 06:15:49 GMTquot;,
          quot;documentquot;:quot;{quot;titlequot;:quot;barquot;}quot;
       }
    ],
    quot;totalquot;:2,
    quot;offsetquot;:0
}
$ curl -i http://localhost:9292/todos/_resolved
$ curl -i http://localhost:9292/todos/_resolved
HTTP/1.1 200 OK
Last-Modified: Thu, 16 Apr 2009 06:25:41 GMT
ETag: quot;59edaebe03b5fe90fa59ef6de633afcequot;
Link: <http://localhost:9292/todos>; rel=quot;indexquot;
Cache-Control: proxy-revalidate
Content-Type: application/json
Content-Length: 369

{
    quot;documentsquot;:[
       {
          quot;etagquot;:quot;55286040-0c7d-012c-af2e-0023dfa0a208quot;,
          quot;uriquot;:quot;/todos/abcquot;,
          quot;last_modifiedquot;:quot;Thu, 16 Apr 2009 06:25:41 GMTquot;,
          quot;documentquot;:quot;{quot;titlequot;:quot;bazquot;}quot;
       },
       {
          quot;etagquot;:quot;9216dde0-0c7b-012c-af2e-0023dfa0a208quot;,
          quot;uriquot;:quot;/todos/9216df80-0c7b-012c-af2e-0023dfa0a208quot;,
          quot;last_modifiedquot;:quot;Thu, 16 Apr 2009 06:13:04 GMTquot;,
          quot;documentquot;:quot;{quot;titlequot;:quot;fooquot;}quot;
     }
    ],
    quot;totalquot;:2,
    quot;offsetquot;:0
}
$ curl -i -XDELETE 
-H'If-Match:55286040-0c7d-012c-af2e-0023dfa0a208' 
http://localhost:9292/todos/abc
$ curl -i -XDELETE 
-H'If-Match:55286040-0c7d-012c-af2e-0023dfa0a208' 
http://localhost:9292/todos/abc
HTTP/1.1 200 OK
Cache-Control: no-cache
Content-Type: application/json
Content-Length: 92

{
    quot;okquot;:true,
    quot;uriquot;:quot;/todos/abc/versions/55286040-0c7d-012c-af2e-0023dfa0a208quot;,
    quot;etagquot;: quot;55286040-0c7d-012c-af2e-0023dfa0a208quot;,
    quot;last_modifiedquot;:quot;Thu, 16 Apr 2009 06:33:50 GMTquot;
}
$ curl -i -XDELETE 
-H'If-Match:55286040-0c7d-012c-af2e-0023dfa0a208' 
http://localhost:9292/todos/abc
HTTP/1.1 200 OK
Cache-Control: no-cache
Content-Type: application/json
Content-Length: 92

{
    quot;okquot;:true,
    quot;uriquot;:quot;/todos/abc/versions/55286040-0c7d-012c-af2e-0023dfa0a208quot;,
    quot;etagquot;: quot;55286040-0c7d-012c-af2e-0023dfa0a208quot;,
    quot;last_modifiedquot;:quot;Thu, 16 Apr 2009 06:33:50 GMTquot;
}
$ curl -i http://localhost:9292/todos/abc
$ curl -i http://localhost:9292/todos/abc
HTTP/1.1 410 Gone
Link: <http://localhost:9292/todos/abc/versions>;
rel=quot;http://joncrosby.me/cloudkit/1.0/rel/versionsquot;
Cache-Control: no-cache
Content-Type: application/json
Content-Length: 37

{quot;errorquot;:quot;entity previously deletedquot;}
$ curl -i http://localhost:9292/todos/abc/versions
$ curl -i http://localhost:9292/todos/abc/versions
HTTP/1.1 200 OK
Last-Modified: Thu, 16 Apr 2009 06:25:41 GMT
ETag: quot;22116ccbc80e6356aec956be63c9c440quot;
Link: <http://localhost:9292/todos/abc/versions/_resolved>; 
rel=quot;http://joncrosby.me/cloudkit/1.0/rel/resolvedquot;
Cache-Control: proxy-revalidate
Content-Type: application/json
Content-Length: 157

{
    quot;urisquot;:[
       quot;/todos/abc/versions/55286040-0c7d-012c-af2e-0023dfa0a208quot;,
       quot;/todos/abc/versions/f4538ca0-0c7b-012c-af2e-0023dfa0a208quot;
    ],
    quot;totalquot;:2,
    quot;offsetquot;:0
}
Uniform Interface
RESTful Collections
Addressable Nouns
Manipulate with HTTP Methods
Expose Relationships with Links
Fully Discoverable API
What’s Missing?
Ability to Ask Questions
Pagination

/todos?page=2&limit=50
Querying

/todos?user=http://joncrosby.me

       /todos?only=title
Uniform Interface
Uniform Interface

 ... for querying?
JSONQuery
                                 Kris Zyp


http://www.sitepen.com/blog/2008/07/16/jsonquery-data-querying-beyond-jsonpath/
XPath
XPath=> JSONPath
 http://goessner.net/articles/JsonPath/
Array Slice Operators


    /todos[10:20]
Array Slice Operators


   /todos[10:20:2]
Comparisons


/todos[?priority>=3]
Chained Expressions


/todos[?priority>=3][0:5]
Extractions


/todos[=name]
Sorting


/todos[/priority][name]
Recursive Finders


/todos[objectid..firstName]
Unions


/todos[?foo=‘bar’,rating=4]
JSONQuery.js
http://github.com/jcrosby/jsonquery
jquery.cloudkit.js
http://github.com/jcrosby/jquery-cloudkit
var store = $.cloudkit;
store.boot({
  success: function() {
     // do something
  },
  error: function(status) {
     // fail gracefully
  }
});
var store = $.cloudkit;
store.boot({
  success: function() {
     // do something
  },
  error: function(status) {
     // fail gracefully
  }
});
var store = $.cloudkit;
store.boot({
  success: function() {
     // do something
  },
  error: function(status) {
     // fail gracefully
  }
});
store.boot
1) Local collection per remote collection
2) Loads remote data
store.boot
1) Local collection per remote collection
2) Loads remote data
store.boot
1) Local collection per remote collection
2) Loads remote data
var store = $.cloudkit;
store.boot({
  success: function() {
     // do something
  },
  error: function(status) {
     // fail gracefully
  }
});
var store = $.cloudkit;
store.boot({
  success: function() {
     // do something
  },
  error: function(status) {
     // fail gracefully
  }
});
// insert a 'todo'
store.collection('todos').create({name:quot;fooquot;}, {
   success: function(todo) {
     // do something with the todo
     alert(todo.json().name);
   }
});
// insert a 'todo'
store.collection('todos').create({name:quot;fooquot;}, {
   success: function(todo) {
     // do something with the todo
     alert(todo.json().name);
   }
});
// insert a 'todo'
store.collection('todos').create({name:quot;fooquot;}, {
   success: function(todo) {
     // do something with the todo
     alert(todo.json().name);
   }
});
// insert a 'todo'
store.collection('todos').create({name:quot;fooquot;}, {
   success: function(todo) {
     // do something with the todo
     alert(todo.json().name);
   }
});
// insert a 'todo'
store.collection('todos').create({name:quot;fooquot;}, {
   success: function(todo) {
     // do something with the todo
     alert(todo.json().name);
   }
});
// update the 'todo'
todo.update({name:quot;barquot;} {
  success: function() {
     // updated remotely, ready for use
     alert(todo.json().name); // now “bar”
  },
  error: function(status) {
     // fail gracefully or recover
  }
});
// update the 'todo'
todo.update({name:quot;barquot;} {
  success: function() {
     // updated remotely, ready for use
     alert(todo.json().name); // now “bar”
  },
  error: function(status) {
     // fail gracefully or recover
  }
});
// update the 'todo'
todo.update({name:quot;barquot;} {
  success: function() {
     // updated remotely, ready for use
     alert(todo.json().name); // now “bar”
  },
  error: function(status) {
     // fail gracefully or recover
  }
});
// update the 'todo'
todo.update({name:quot;barquot;} {
  success: function() {
     // updated remotely, ready for use
     alert(todo.json().name); // now “bar”
  },
  error: function(status) {
     // fail gracefully or recover
  }
});
// update the 'todo'
todo.update({name:quot;barquot;} {
  success: function() {
     // updated remotely, ready for use
     alert(todo.json().name); // now “bar”
  },
  error: function(status) {
     // fail gracefully or recover
  }
});
Recovery
410 => Remove Locally? Create New?
Recovery
410 => Remove Locally? Create New?
412 => Progressive Diff/Merge
Recovery
410 => Remove Locally? Create New?
412 => Progressive Diff/Merge (Sync)
// delete the 'todo'
todo.destroy({
  success: function() {
    // the 'todo' has now been deleted
  }
});
// delete the 'todo'
todo.destroy({
  success: function() {
    // the 'todo' has now been deleted
  }
});
// delete the 'todo'
todo.destroy({
  success: function() {
    // the 'todo' has now been deleted
  }
});
// delete the 'todo'
todo.destroy({
  success: function() {
    // the 'todo' has now been deleted
  }
});
store.collection('todos').query(quot;?name='foo'quot;);
Johnson

        Ruby/JavaScript Bridge



http://github.com/jbarnette/johnson
1.0 Roadmap
JSONSchema

        /:collection/_schema


http://www.json.com/json-schema-proposal/
{
    quot;descriptionquot;:quot;A personquot;,
    quot;typequot;:quot;objectquot;,
    quot;propertiesquot;: {
      quot;namequot;: {
         quot;typequot;:quot;stringquot;
      },
      quot;agequot;: {
         quot;typequot;:quot;integerquot;,
         quot;maximumquot;:125
      }
    }
}
Open Web
 JSON
Appliance
Open Web
 JSON
Appliance
require ‘cloudkit’
expose :todos, :profiles
require ‘cloudkit’
contain :todos, :profiles
OpenID
      +
    OAuth
      +
OAuth/Discovery
Browser


OAuth    OpenID   Service
Browser


OAuth    OpenID   Service
Browser


        {...}
OAuth            OpenID   Service
Browser


OAuth    OpenID   Service
Browser


OAuth    OpenID   Service

          {...}

          Login
Browser


OAuth    OpenID   Service
Browser


OAuth    OpenID   Service
Browser


OAuth    OpenID   Service
Service or Desktop App


OAuth     OpenID     Service
Service or Desktop App


OAuth     OpenID     Service
Service or Desktop App


        {...}
OAuth           OpenID   Service
Service or Desktop App


OAuth     OpenID     Service
Service or Desktop App


OAuth     OpenID     Service

           {...}

           Login
curl -i http://localhost:9292/todos
HTTP/1.1 401 Unauthorized
Connection: close
Date: Thu, 15 Jan 2009 22:24:23 GMT
WWW-Authenticate: OAuth realm=quot;http://localhost:9292quot;
Link: <http://localhost:9292/oauth/meta>;
rel=quot;http://oauth.net/discovery/1.0/rel/providerquot;
Content-Type: text/html
Set-Cookie: rack.session=d6b1c6aa6d463a478eb9af0e921eb997;
path=/; HttpOnly
Content-Length: 1280

<!DOCTYPE html PUBLIC quot;-//W3C//DTD XHTML 1.0 Transitional//ENquot;
   quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtdquot;>
<html xmlns=quot;http://www.w3.org/1999/xhtmlquot; xml:lang=quot;enquot; lang=quot;enquot;>
... etc ...
$ curl -i http://localhost:9292/oauth/meta
$ curl -i http://localhost:9292/oauth/meta

<?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?>
<XRD>
 <Type>http://oauth.net/discovery/1.0</Type>
 <Service>
  <Type>http://oauth.net/discovery/1.0/rel/provider</Type>
  <URI>http://localhost:9292/oauth</URI>
 </Service>
</XRD>
$ curl -i http://localhost:9292/oauth
(squint)
<?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?>
<XRDS xmlns=quot;xri://$xrdsquot;>
 <XRD xml:id=quot;oauthquot; xmlns:simple=quot;http://xrds-simple.net/core/1.0quot; xmlns=quot;xri://$XRD*($v*2.0)quot; version=quot;2.0quot;>
  <Type>xri://$xrds*simple</Type>
  <Expires>2009-02-14T22:27:50Z</Expires>
  <Service priority=quot;10quot;>
   <Type>http://oauth.net/core/1.0/endpoint/request</Type>
   <Type>http://oauth.net/core/1.0/parameters/auth-header</Type>
   <Type>http://oauth.net/core/1.0/parameters/uri-query</Type>
   <Type>http://oauth.net/core/1.0/signature/PLAINTEXT</Type>
   <URI>http://localhost:9292/oauth/request_tokens</URI>
  </Service>
  <Service priority=quot;10quot;>
   <Type>http://oauth.net/core/1.0/endpoint/authorize</Type>
   <Type>http://oauth.net/core/1.0/parameters/uri-query</Type>
   <URI>http://localhost:9292/oauth/authorization</URI>
  </Service>
  <Service priority=quot;10quot;>
   <Type>http://oauth.net/core/1.0/endpoint/access</Type>
   <Type>http://oauth.net/core/1.0/parameters/auth-header</Type>
   <Type>http://oauth.net/core/1.0/parameters/uri-query</Type>
   <Type>http://oauth.net/core/1.0/signature/PLAINTEXT</Type>
   <URI>http://localhost:9292/oauth/access_tokens</URI>
  </Service>
  <Service priority=quot;10quot;>
   <Type>http://oauth.net/core/1.0/endpoint/resource</Type>
   <Type>http://oauth.net/core/1.0/parameters/auth-header</Type>
   <Type>http://oauth.net/core/1.0/parameters/uri-query</Type>
   <Type>http://oauth.net/core/1.0/signature/HMAC-SHA1</Type>
  </Service>
  <Service priority=quot;10quot;>
   <Type>http://oauth.net/discovery/1.0/consumer-identity/static</Type>
   <LocalID>cloudkitconsumer</LocalID>
  </Service>
 </XRD>
 <XRD xmlns=quot;xri://$XRD*($v*2.0)quot; version=quot;2.0quot;>
  <Type>xri://$xrds*simple</Type>
  <Service priority=quot;10quot;>
   <Type>http://oauth.net/discovery/1.0</Type>
   <URI>#oauth</URI>
  </Service>
 </XRD>
</XRDS>
Service or Desktop App


OAuth     OpenID     Service
Service or Desktop App


OAuth     OpenID     Service
Service or Desktop App


OAuth     OpenID     Service
Service or Desktop App


OAuth     OpenID     Service
1.0
JSONQuery Release
JSONSchema Release
Templating
Done
CloudKit
http://getcloudkit.com
 http://joncrosby.me

More Related Content

Similar to CloudKit

Service Oriented Integration With ServiceMix
Service Oriented Integration With ServiceMixService Oriented Integration With ServiceMix
Service Oriented Integration With ServiceMixBruce Snyder
 
Velocity EU 2012 - Third party scripts and you
Velocity EU 2012 - Third party scripts and youVelocity EU 2012 - Third party scripts and you
Velocity EU 2012 - Third party scripts and youPatrick Meenan
 
Consegi 2010 - Dicas de Desenvolvimento Web com Ruby
Consegi 2010 - Dicas de Desenvolvimento Web com RubyConsegi 2010 - Dicas de Desenvolvimento Web com Ruby
Consegi 2010 - Dicas de Desenvolvimento Web com RubyFabio Akita
 
Rails Presentation (Anton Dmitriyev)
Rails Presentation (Anton Dmitriyev)Rails Presentation (Anton Dmitriyev)
Rails Presentation (Anton Dmitriyev)True-Vision
 
Stefan Judis "Did we(b development) lose the right direction?"
Stefan Judis "Did we(b development) lose the right direction?"Stefan Judis "Did we(b development) lose the right direction?"
Stefan Judis "Did we(b development) lose the right direction?"Fwdays
 
Cross Domain Web
Mashups with JQuery and Google App Engine
Cross Domain Web
Mashups with JQuery and Google App EngineCross Domain Web
Mashups with JQuery and Google App Engine
Cross Domain Web
Mashups with JQuery and Google App EngineAndy McKay
 
Teflon - Anti Stick for the browser attack surface
Teflon - Anti Stick for the browser attack surfaceTeflon - Anti Stick for the browser attack surface
Teflon - Anti Stick for the browser attack surfaceSaumil Shah
 
Socket applications
Socket applicationsSocket applications
Socket applicationsJoão Moura
 
More Secrets of JavaScript Libraries
More Secrets of JavaScript LibrariesMore Secrets of JavaScript Libraries
More Secrets of JavaScript Librariesjeresig
 
cdac@parag.gajbhiye@test123
cdac@parag.gajbhiye@test123cdac@parag.gajbhiye@test123
cdac@parag.gajbhiye@test123Parag Gajbhiye
 
Beyond the Node: Arkestration with Noah
Beyond the Node: Arkestration with NoahBeyond the Node: Arkestration with Noah
Beyond the Node: Arkestration with Noahlusis
 
Application Security for Rich Internet Applicationss (Jfokus 2012)
Application Security for Rich Internet Applicationss (Jfokus 2012)Application Security for Rich Internet Applicationss (Jfokus 2012)
Application Security for Rich Internet Applicationss (Jfokus 2012)johnwilander
 
Plone Interactivity
Plone InteractivityPlone Interactivity
Plone InteractivityEric Steele
 
Zero to Sixty: AWS Elastic Beanstalk (DMG204) | AWS re:Invent 2013
Zero to Sixty: AWS Elastic Beanstalk (DMG204) | AWS re:Invent 2013Zero to Sixty: AWS Elastic Beanstalk (DMG204) | AWS re:Invent 2013
Zero to Sixty: AWS Elastic Beanstalk (DMG204) | AWS re:Invent 2013Amazon Web Services
 
Mobile web-debug
Mobile web-debugMobile web-debug
Mobile web-debugFINN.no
 
0-60 with Goliath: Building High Performance Ruby Web-Services
0-60 with Goliath: Building High Performance Ruby Web-Services0-60 with Goliath: Building High Performance Ruby Web-Services
0-60 with Goliath: Building High Performance Ruby Web-ServicesIlya Grigorik
 
Enabling Microservices @Orbitz - Velocity Conf 2015
Enabling Microservices @Orbitz - Velocity Conf 2015Enabling Microservices @Orbitz - Velocity Conf 2015
Enabling Microservices @Orbitz - Velocity Conf 2015Steve Hoffman
 

Similar to CloudKit (20)

Service Oriented Integration With ServiceMix
Service Oriented Integration With ServiceMixService Oriented Integration With ServiceMix
Service Oriented Integration With ServiceMix
 
Velocity EU 2012 - Third party scripts and you
Velocity EU 2012 - Third party scripts and youVelocity EU 2012 - Third party scripts and you
Velocity EU 2012 - Third party scripts and you
 
Consegi 2010 - Dicas de Desenvolvimento Web com Ruby
Consegi 2010 - Dicas de Desenvolvimento Web com RubyConsegi 2010 - Dicas de Desenvolvimento Web com Ruby
Consegi 2010 - Dicas de Desenvolvimento Web com Ruby
 
Rails Presentation (Anton Dmitriyev)
Rails Presentation (Anton Dmitriyev)Rails Presentation (Anton Dmitriyev)
Rails Presentation (Anton Dmitriyev)
 
Stefan Judis "Did we(b development) lose the right direction?"
Stefan Judis "Did we(b development) lose the right direction?"Stefan Judis "Did we(b development) lose the right direction?"
Stefan Judis "Did we(b development) lose the right direction?"
 
Celix universal OSGi
Celix universal OSGiCelix universal OSGi
Celix universal OSGi
 
JSON Viewer XPATH Workbook
JSON Viewer XPATH WorkbookJSON Viewer XPATH Workbook
JSON Viewer XPATH Workbook
 
Cross Domain Web
Mashups with JQuery and Google App Engine
Cross Domain Web
Mashups with JQuery and Google App EngineCross Domain Web
Mashups with JQuery and Google App Engine
Cross Domain Web
Mashups with JQuery and Google App Engine
 
Teflon - Anti Stick for the browser attack surface
Teflon - Anti Stick for the browser attack surfaceTeflon - Anti Stick for the browser attack surface
Teflon - Anti Stick for the browser attack surface
 
Socket applications
Socket applicationsSocket applications
Socket applications
 
More Secrets of JavaScript Libraries
More Secrets of JavaScript LibrariesMore Secrets of JavaScript Libraries
More Secrets of JavaScript Libraries
 
cdac@parag.gajbhiye@test123
cdac@parag.gajbhiye@test123cdac@parag.gajbhiye@test123
cdac@parag.gajbhiye@test123
 
Beyond the Node: Arkestration with Noah
Beyond the Node: Arkestration with NoahBeyond the Node: Arkestration with Noah
Beyond the Node: Arkestration with Noah
 
Application Security for Rich Internet Applicationss (Jfokus 2012)
Application Security for Rich Internet Applicationss (Jfokus 2012)Application Security for Rich Internet Applicationss (Jfokus 2012)
Application Security for Rich Internet Applicationss (Jfokus 2012)
 
Plone Interactivity
Plone InteractivityPlone Interactivity
Plone Interactivity
 
Zero to Sixty: AWS Elastic Beanstalk (DMG204) | AWS re:Invent 2013
Zero to Sixty: AWS Elastic Beanstalk (DMG204) | AWS re:Invent 2013Zero to Sixty: AWS Elastic Beanstalk (DMG204) | AWS re:Invent 2013
Zero to Sixty: AWS Elastic Beanstalk (DMG204) | AWS re:Invent 2013
 
Mobile web-debug
Mobile web-debugMobile web-debug
Mobile web-debug
 
0-60 with Goliath: Building High Performance Ruby Web-Services
0-60 with Goliath: Building High Performance Ruby Web-Services0-60 with Goliath: Building High Performance Ruby Web-Services
0-60 with Goliath: Building High Performance Ruby Web-Services
 
Enabling Microservices @Orbitz - Velocity Conf 2015
Enabling Microservices @Orbitz - Velocity Conf 2015Enabling Microservices @Orbitz - Velocity Conf 2015
Enabling Microservices @Orbitz - Velocity Conf 2015
 
Web Application Defences
Web Application DefencesWeb Application Defences
Web Application Defences
 

Recently uploaded

Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfRankYa
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfPrecisely
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clashcharlottematthew16
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsRizwan Syed
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionDilum Bandara
 

Recently uploaded (20)

Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdf
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clash
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL Certs
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An Introduction
 

CloudKit

  • 1. +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 1
  • 3.
  • 4. Engine Yard Solo “The platform for on-demand management of your Ruby on Rails application in the cloud.”
  • 9. RESTful Collections of JSON Documents
  • 11. Ruby
  • 12. $ gem install cloudkit
  • 15. 2009
  • 18. Rails 3 => API
  • 19. framework = { :orm => AR :dispatcher => AD}.merge( :orm => YourORM)
  • 20. framework = { :orm => AR :dispatcher => AD}.merge( :orm => YourORM)
  • 21. framework = { :orm => AR :dispatcher => AD}.merge( :orm => YourORM)
  • 22. ! MVC
  • 23. ! MVC “in the back?”
  • 26. Resource Composition in the Browser A.S. Focus
  • 27. Resource Composition in the Browser A.S. Focus
  • 28. Resource Composition in the Browser A.S. Focus
  • 32. ESI Caching Layer REST Fragment A Service Client REST Fragment B Service
  • 35. Rack
  • 37.
  • 38. HTTP
  • 40. Intermediaries App HTTP
  • 41. Intermediaries App HTTP
  • 42. Intermediaries Rack HTTP
  • 43.
  • 44. HTTP
  • 47. Middleware App HTTP
  • 48. Rack is the Web
  • 53. REST
  • 54. Roy Fielding Architectural Styles and the Design of Network-based Software Architectures http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm
  • 58. Done
  • 60. $ curl -i http://localhost:9292/cloudkit-meta
  • 61. $ curl -i http://localhost:9292/cloudkit-meta HTTP/1.1 200 OK ETag: quot;5b6f484abf2d95cec3ea8867d1754418quot; Cache-Control: proxy-revalidate Content-Type: application/json Content-Length: 33 {quot;urisquot;:[quot;/todosquot;,quot;/profilesquot;]}
  • 62. $ curl -i -XOPTIONS http://localhost:9292/todos
  • 63. $ curl -i -XOPTIONS http://localhost:9292/todos HTTP/1.1 200 OK Content-Type: application/json Content-Length: 0 Allow: GET, HEAD, POST, OPTIONS
  • 64. $ curl -i http://localhost:9292/todos
  • 65. $ curl -i http://localhost:9292/todos HTTP/1.1 200 OK ETag: quot;df392c5664e6ecd64b83210fb925f6c8quot; Link: <http://localhost:9292/todos/_resolved>; rel=quot;http://joncrosby.me/cloudkit/1.0/rel/resolvedquot; Cache-Control: proxy-revalidate Content-Type: application/json Content-Length: 32 {quot;urisquot;:[],quot;totalquot;:0,quot;offsetquot;:0}
  • 66. $ curl -i http://localhost:9292/todos HTTP/1.1 200 OK ETag: quot;df392c5664e6ecd64b83210fb925f6c8quot; Link: <http://localhost:9292/todos/_resolved>; rel=quot;http://joncrosby.me/cloudkit/1.0/rel/resolvedquot; Cache-Control: proxy-revalidate Content-Type: application/json Content-Length: 32 {quot;urisquot;:[],quot;totalquot;:0,quot;offsetquot;:0}
  • 67. $ curl -i http://localhost:9292/todos HTTP/1.1 200 OK ETag: quot;df392c5664e6ecd64b83210fb925f6c8quot; Link: <http://localhost:9292/todos/_resolved>; rel=quot;http://joncrosby.me/cloudkit/1.0/rel/resolvedquot; Cache-Control: proxy-revalidate Content-Type: application/json Content-Length: 32 {quot;urisquot;:[],quot;totalquot;:0,quot;offsetquot;:0}
  • 68. $ curl -i http://localhost:9292/todos HTTP/1.1 200 OK ETag: quot;df392c5664e6ecd64b83210fb925f6c8quot; Link: <http://localhost:9292/todos/_resolved>; rel=quot;http://joncrosby.me/cloudkit/1.0/rel/resolvedquot; Cache-Control: proxy-revalidate Content-Type: application/json Content-Length: 32 {quot;urisquot;:[],quot;totalquot;:0,quot;offsetquot;:0}
  • 69. Link Relations and HTTP Header Linking IETF Draft by Mark Nottingham http://tools.ietf.org/html/draft-nottingham-http-link-header-04
  • 70. Hypermedia as the Engine of Application State -- Fielding
  • 71. Connectedness -- Richardson, Ruby
  • 72. $ curl -i -XPOST -d'{quot;titlequot;:quot;fooquot;}' http://localhost:9292/todos
  • 73. $ curl -i -XPOST -d'{quot;titlequot;:quot;fooquot;}' http://localhost:9292/todos HTTP/1.1 201 Created Cache-Control: no-cache Content-Type: application/json Content-Length: 159 { quot;okquot;:true, quot;uriquot;:quot;/todos/9216df80-0c7b-012c-af2e-0023dfa0a208quot;, quot;etagquot;:quot;9216dde0-0c7b-012c-af2e-0023dfa0a208quot;, quot;last_modifiedquot;:quot;Thu, 16 Apr 2009 06:13:04 GMTquot; }
  • 76. Metadata + Document
  • 77. URI, ETag, Last-Modified, etc. + Document
  • 78. SQL
  • 79. ORM
  • 82. todos[“random_id”] = { “uri” => “/todos/abc”, “etag” => “9216dde0-0c7b-012c”, “last_modified” => “Thu, 16 Apr 2009 06:13:04 GMT”, “remote_user” => “http://joncrosby.me”, “json” => “{”title”:”foo”}”, ... }
  • 83. Rufus::Tokyo record = store.query { |q| q.add_condition(“uri”, :eql, “/todos/abc”) }
  • 86. HTTP and JSON are the Schema
  • 87. $ curl -i -XPUT -d'{quot;titlequot;:quot;barquot;}' http://localhost:9292/todos/abc
  • 88. $ curl -i -XPUT -d'{quot;titlequot;:quot;barquot;}' http://localhost:9292/todos/abc HTTP/1.1 201 Created Cache-Control: no-cache Content-Type: application/json Content-Length: 126 { quot;okquot;:true, quot;uriquot;:quot;/todos/abcquot;, quot;etagquot;:quot;f4538ca0-0c7b-012c-af2e-0023dfa0a208quot;, quot;last_modifiedquot;:quot;Thu, 16 Apr 2009 06:15:49 GMTquot; }
  • 89. $ curl -i -XOPTIONS http://localhost:9292/todos/abc
  • 90. $ curl -i -XOPTIONS http://localhost:9292/todos/abc HTTP/1.1 200 OK Content-Type: application/json Content-Length: 0 Allow: GET, HEAD, PUT, DELETE, OPTIONS
  • 91. $ curl -i http://localhost:9292/todos/abc
  • 92. $ curl -i http://localhost:9292/todos/abc HTTP/1.1 200 OK Last-Modified: Thu, 16 Apr 2009 06:15:49 GMT ETag: quot;f4538ca0-0c7b-012c-af2e-0023dfa0a208quot; Link: <http://localhost:9292/todos/abc/versions>; rel=quot;http://joncrosby.me/cloudkit/1.0/rel/versionsquot; Cache-Control: proxy-revalidate Content-Type: application/json Content-Length: 15 {quot;titlequot;:quot;barquot;}
  • 93. $ curl -i http://localhost:9292/todos/abc HTTP/1.1 200 OK Last-Modified: Thu, 16 Apr 2009 06:15:49 GMT ETag: quot;f4538ca0-0c7b-012c-af2e-0023dfa0a208quot; Link: <http://localhost:9292/todos/abc/versions>; rel=quot;http://joncrosby.me/cloudkit/1.0/rel/versionsquot; Cache-Control: proxy-revalidate Content-Type: application/json Content-Length: 15 {quot;titlequot;:quot;barquot;}
  • 94. $ curl -i http://localhost:9292/todos/abc HTTP/1.1 200 OK Last-Modified: Thu, 16 Apr 2009 06:15:49 GMT ETag: quot;f4538ca0-0c7b-012c-af2e-0023dfa0a208quot; Link: <http://localhost:9292/todos/abc/versions>; rel=quot;http://joncrosby.me/cloudkit/1.0/rel/versionsquot; Cache-Control: proxy-revalidate Content-Type: application/json Content-Length: 15 {quot;titlequot;:quot;barquot;}
  • 95. $ curl -i http://localhost:9292/todos/abc HTTP/1.1 200 OK Last-Modified: Thu, 16 Apr 2009 06:15:49 GMT ETag: quot;f4538ca0-0c7b-012c-af2e-0023dfa0a208quot; Link: <http://localhost:9292/todos/abc/versions>; rel=quot;http://joncrosby.me/cloudkit/1.0/rel/versionsquot; Cache-Control: proxy-revalidate Content-Type: application/json Content-Length: 15 {quot;titlequot;:quot;barquot;}
  • 102. $ curl -i http://localhost:9292/todos
  • 103. $ curl -i http://localhost:9292/todos HTTP/1.1 200 OK Last-Modified: Thu, 16 Apr 2009 06:15:49 GMT ETag: quot;0aca58964aa2e15a9365d72dd4c43472quot; Link: <http://localhost:9292/todos/_resolved>; rel=quot;http://joncrosby.me/cloudkit/1.0/rel/resolvedquot; Cache-Control: proxy-revalidate Content-Type: application/json Content-Length: 94 { quot;urisquot;:[ quot;/todos/abcquot;, quot;/todos/9216df80-0c7b-012c-af2e-0023dfa0a208quot; ], quot;totalquot;:2, quot;offsetquot;:0 }
  • 108. 2 Users 2 Browsers 1 Document
  • 109. 2 Users 2 Browsers 1 Document Fight!
  • 110. 2 Users 2 Browsers 1 Document Hand Wave!
  • 111. $ curl -i -XPUT -d'{quot;titlequot;:quot;bazquot;}' http://localhost:9292/todos/abc
  • 112. $ curl -i -XPUT -d'{quot;titlequot;:quot;bazquot;}' http://localhost:9292/todos/abc HTTP/1.1 400 Bad Request Cache-Control: no-cache Content-Type: application/json Content-Length: 25 {quot;errorquot;:quot;etag requiredquot;}
  • 113. $ curl -i -XPUT -H'If-Match:f4538ca0-0c7b-012c-af2e-0023dfa0a208' -d'{quot;titlequot;:quot;bazquot;}' http://localhost:9292/todos/abc
  • 114. $ curl -i -XPUT -H'If-Match:f4538ca0-0c7b-012c-af2e-0023dfa0a208' -d'{quot;titlequot;:quot;bazquot;}' http://localhost:9292/todos/abc HTTP/1.1 200 OK Cache-Control: no-cache Content-Type: application/json Content-Length: 126 { quot;okquot;:true, quot;uriquot;:quot;/todos/abcquot;, quot;etagquot;:quot;55286040-0c7d-012c-af2e-0023dfa0a208quot;, quot;last_modifiedquot;:quot;Thu, 16 Apr 2009 06:25:41 GMTquot; }
  • 115. $ curl -i -XPUT -H'If-Match:f4538ca0-0c7b-012c-af2e-0023dfa0a208' -d'{quot;titlequot;:quot;boxquot;}' http://localhost:9292/todos/abc
  • 116. $ curl -i -XPUT -H'If-Match:f4538ca0-0c7b-012c-af2e-0023dfa0a208' -d'{quot;titlequot;:quot;boxquot;}' http://localhost:9292/todos/abc HTTP/1.1 412 Precondition Failed Cache-Control: no-cache Content-Type: application/json Content-Length: 31 {quot;errorquot;:quot;precondition failedquot;}
  • 117. $ curl -i http://localhost:9292/todos/abc/versions
  • 118. $ curl -i http://localhost:9292/todos/abc/versions HTTP/1.1 200 OK Last-Modified: Thu, 16 Apr 2009 06:25:41 GMT ETag: quot;f7aae4894429a39c7c3fe0c8ea9aa00equot; Link: <http://localhost:9292/todos/abc/versions/_resolved>; rel=quot;http://joncrosby.me/cloudkit/1.0/rel/resolvedquot; Cache-Control: proxy-revalidate Content-Type: application/json Content-Length: 109 { quot;urisquot;:[ quot;/todos/abcquot;, quot;/todos/abc/versions/f4538ca0-0c7b-012caf2e-0023dfa0a208quot; ], quot;totalquot;:2, quot;offsetquot;:0 }
  • 119. $ curl -i http://localhost:9292/todos/abc/versions HTTP/1.1 200 OK Last-Modified: Thu, 16 Apr 2009 06:25:41 GMT ETag: quot;f7aae4894429a39c7c3fe0c8ea9aa00equot; Link: <http://localhost:9292/todos/abc/versions/_resolved>; rel=quot;http://joncrosby.me/cloudkit/1.0/rel/resolvedquot; Cache-Control: proxy-revalidate Content-Type: application/json Content-Length: 109 { quot;urisquot;:[ quot;/todos/abcquot;, quot;/todos/abc/versions/f4538ca0-0c7b-012caf2e-0023dfa0a208quot; ], quot;totalquot;:2, quot;offsetquot;:0 }
  • 121. O(n)
  • 122. 1000 documents = 1001 GETs
  • 123. :-(
  • 124. Time to rewrite in Scala?
  • 125. $ curl -i http://localhost:9292/todos/abc/versions/_resolved
  • 126. $ curl -i http://localhost:9292/todos/abc/versions/_resolved HTTP/1.1 200 OK Last-Modified: Thu, 16 Apr 2009 06:25:41 GMT ETag: quot;ea2238f8f2da37b70f3d2f09464f166equot; Link: <http://localhost:9292/todos/abc/versions>; rel=quot;indexquot; Cache-Control: proxy-revalidate Content-Type: application/json Content-Length: 384 { quot;documentsquot;:[ { quot;etagquot;:quot;55286040-0c7d-012c-af2e-0023dfa0a208quot;, quot;uriquot;:quot;/todos/abcquot;, quot;last_modifiedquot;:quot;Thu, 16 Apr 2009 06:25:41 GMTquot;, quot;documentquot;:quot;{quot;titlequot;:quot;bazquot;}quot; }, { quot;etagquot;:quot;f4538ca0-0c7b-012c-af2e-0023dfa0a208quot;, quot;uriquot;:quot;/todos/abc/versions/f4538ca0-0c7b-012c-af2e-0023dfa0a208quot;, quot;last_modifiedquot;:quot;Thu, 16 Apr 2009 06:15:49 GMTquot;, quot;documentquot;:quot;{quot;titlequot;:quot;barquot;}quot; } ], quot;totalquot;:2, quot;offsetquot;:0 }
  • 127. $ curl -i http://localhost:9292/todos/abc/versions/_resolved HTTP/1.1 200 OK Last-Modified: Thu, 16 Apr 2009 06:25:41 GMT ETag: quot;ea2238f8f2da37b70f3d2f09464f166equot; Link: <http://localhost:9292/todos/abc/versions>; rel=quot;indexquot; Cache-Control: proxy-revalidate Content-Type: application/json Content-Length: 384 { quot;documentsquot;:[ { quot;etagquot;:quot;55286040-0c7d-012c-af2e-0023dfa0a208quot;, quot;uriquot;:quot;/todos/abcquot;, quot;last_modifiedquot;:quot;Thu, 16 Apr 2009 06:25:41 GMTquot;, quot;documentquot;:quot;{quot;titlequot;:quot;bazquot;}quot; }, { quot;etagquot;:quot;f4538ca0-0c7b-012c-af2e-0023dfa0a208quot;, quot;uriquot;:quot;/todos/abc/versions/f4538ca0-0c7b-012c-af2e-0023dfa0a208quot;, quot;last_modifiedquot;:quot;Thu, 16 Apr 2009 06:15:49 GMTquot;, quot;documentquot;:quot;{quot;titlequot;:quot;barquot;}quot; } ], quot;totalquot;:2, quot;offsetquot;:0 }
  • 128. $ curl -i http://localhost:9292/todos/_resolved
  • 129. $ curl -i http://localhost:9292/todos/_resolved HTTP/1.1 200 OK Last-Modified: Thu, 16 Apr 2009 06:25:41 GMT ETag: quot;59edaebe03b5fe90fa59ef6de633afcequot; Link: <http://localhost:9292/todos>; rel=quot;indexquot; Cache-Control: proxy-revalidate Content-Type: application/json Content-Length: 369 { quot;documentsquot;:[ { quot;etagquot;:quot;55286040-0c7d-012c-af2e-0023dfa0a208quot;, quot;uriquot;:quot;/todos/abcquot;, quot;last_modifiedquot;:quot;Thu, 16 Apr 2009 06:25:41 GMTquot;, quot;documentquot;:quot;{quot;titlequot;:quot;bazquot;}quot; }, { quot;etagquot;:quot;9216dde0-0c7b-012c-af2e-0023dfa0a208quot;, quot;uriquot;:quot;/todos/9216df80-0c7b-012c-af2e-0023dfa0a208quot;, quot;last_modifiedquot;:quot;Thu, 16 Apr 2009 06:13:04 GMTquot;, quot;documentquot;:quot;{quot;titlequot;:quot;fooquot;}quot; } ], quot;totalquot;:2, quot;offsetquot;:0 }
  • 130. $ curl -i -XDELETE -H'If-Match:55286040-0c7d-012c-af2e-0023dfa0a208' http://localhost:9292/todos/abc
  • 131. $ curl -i -XDELETE -H'If-Match:55286040-0c7d-012c-af2e-0023dfa0a208' http://localhost:9292/todos/abc HTTP/1.1 200 OK Cache-Control: no-cache Content-Type: application/json Content-Length: 92 { quot;okquot;:true, quot;uriquot;:quot;/todos/abc/versions/55286040-0c7d-012c-af2e-0023dfa0a208quot;, quot;etagquot;: quot;55286040-0c7d-012c-af2e-0023dfa0a208quot;, quot;last_modifiedquot;:quot;Thu, 16 Apr 2009 06:33:50 GMTquot; }
  • 132. $ curl -i -XDELETE -H'If-Match:55286040-0c7d-012c-af2e-0023dfa0a208' http://localhost:9292/todos/abc HTTP/1.1 200 OK Cache-Control: no-cache Content-Type: application/json Content-Length: 92 { quot;okquot;:true, quot;uriquot;:quot;/todos/abc/versions/55286040-0c7d-012c-af2e-0023dfa0a208quot;, quot;etagquot;: quot;55286040-0c7d-012c-af2e-0023dfa0a208quot;, quot;last_modifiedquot;:quot;Thu, 16 Apr 2009 06:33:50 GMTquot; }
  • 133. $ curl -i http://localhost:9292/todos/abc
  • 134. $ curl -i http://localhost:9292/todos/abc HTTP/1.1 410 Gone Link: <http://localhost:9292/todos/abc/versions>; rel=quot;http://joncrosby.me/cloudkit/1.0/rel/versionsquot; Cache-Control: no-cache Content-Type: application/json Content-Length: 37 {quot;errorquot;:quot;entity previously deletedquot;}
  • 135. $ curl -i http://localhost:9292/todos/abc/versions
  • 136. $ curl -i http://localhost:9292/todos/abc/versions HTTP/1.1 200 OK Last-Modified: Thu, 16 Apr 2009 06:25:41 GMT ETag: quot;22116ccbc80e6356aec956be63c9c440quot; Link: <http://localhost:9292/todos/abc/versions/_resolved>; rel=quot;http://joncrosby.me/cloudkit/1.0/rel/resolvedquot; Cache-Control: proxy-revalidate Content-Type: application/json Content-Length: 157 { quot;urisquot;:[ quot;/todos/abc/versions/55286040-0c7d-012c-af2e-0023dfa0a208quot;, quot;/todos/abc/versions/f4538ca0-0c7b-012c-af2e-0023dfa0a208quot; ], quot;totalquot;:2, quot;offsetquot;:0 }
  • 144. Ability to Ask Questions
  • 148. Uniform Interface ... for querying?
  • 149. JSONQuery Kris Zyp http://www.sitepen.com/blog/2008/07/16/jsonquery-data-querying-beyond-jsonpath/
  • 150. XPath
  • 152. Array Slice Operators /todos[10:20]
  • 153. Array Slice Operators /todos[10:20:2]
  • 162. var store = $.cloudkit; store.boot({ success: function() { // do something }, error: function(status) { // fail gracefully } });
  • 163. var store = $.cloudkit; store.boot({ success: function() { // do something }, error: function(status) { // fail gracefully } });
  • 164. var store = $.cloudkit; store.boot({ success: function() { // do something }, error: function(status) { // fail gracefully } });
  • 165. store.boot 1) Local collection per remote collection 2) Loads remote data
  • 166. store.boot 1) Local collection per remote collection 2) Loads remote data
  • 167. store.boot 1) Local collection per remote collection 2) Loads remote data
  • 168. var store = $.cloudkit; store.boot({ success: function() { // do something }, error: function(status) { // fail gracefully } });
  • 169. var store = $.cloudkit; store.boot({ success: function() { // do something }, error: function(status) { // fail gracefully } });
  • 170. // insert a 'todo' store.collection('todos').create({name:quot;fooquot;}, { success: function(todo) { // do something with the todo alert(todo.json().name); } });
  • 171. // insert a 'todo' store.collection('todos').create({name:quot;fooquot;}, { success: function(todo) { // do something with the todo alert(todo.json().name); } });
  • 172. // insert a 'todo' store.collection('todos').create({name:quot;fooquot;}, { success: function(todo) { // do something with the todo alert(todo.json().name); } });
  • 173. // insert a 'todo' store.collection('todos').create({name:quot;fooquot;}, { success: function(todo) { // do something with the todo alert(todo.json().name); } });
  • 174. // insert a 'todo' store.collection('todos').create({name:quot;fooquot;}, { success: function(todo) { // do something with the todo alert(todo.json().name); } });
  • 175. // update the 'todo' todo.update({name:quot;barquot;} { success: function() { // updated remotely, ready for use alert(todo.json().name); // now “bar” }, error: function(status) { // fail gracefully or recover } });
  • 176. // update the 'todo' todo.update({name:quot;barquot;} { success: function() { // updated remotely, ready for use alert(todo.json().name); // now “bar” }, error: function(status) { // fail gracefully or recover } });
  • 177. // update the 'todo' todo.update({name:quot;barquot;} { success: function() { // updated remotely, ready for use alert(todo.json().name); // now “bar” }, error: function(status) { // fail gracefully or recover } });
  • 178. // update the 'todo' todo.update({name:quot;barquot;} { success: function() { // updated remotely, ready for use alert(todo.json().name); // now “bar” }, error: function(status) { // fail gracefully or recover } });
  • 179. // update the 'todo' todo.update({name:quot;barquot;} { success: function() { // updated remotely, ready for use alert(todo.json().name); // now “bar” }, error: function(status) { // fail gracefully or recover } });
  • 180. Recovery 410 => Remove Locally? Create New?
  • 181. Recovery 410 => Remove Locally? Create New? 412 => Progressive Diff/Merge
  • 182. Recovery 410 => Remove Locally? Create New? 412 => Progressive Diff/Merge (Sync)
  • 183. // delete the 'todo' todo.destroy({ success: function() { // the 'todo' has now been deleted } });
  • 184. // delete the 'todo' todo.destroy({ success: function() { // the 'todo' has now been deleted } });
  • 185. // delete the 'todo' todo.destroy({ success: function() { // the 'todo' has now been deleted } });
  • 186. // delete the 'todo' todo.destroy({ success: function() { // the 'todo' has now been deleted } });
  • 188.
  • 189. Johnson Ruby/JavaScript Bridge http://github.com/jbarnette/johnson
  • 191. JSONSchema /:collection/_schema http://www.json.com/json-schema-proposal/
  • 192. { quot;descriptionquot;:quot;A personquot;, quot;typequot;:quot;objectquot;, quot;propertiesquot;: { quot;namequot;: { quot;typequot;:quot;stringquot; }, quot;agequot;: { quot;typequot;:quot;integerquot;, quot;maximumquot;:125 } } }
  • 197. OpenID + OAuth + OAuth/Discovery
  • 198. Browser OAuth OpenID Service
  • 199. Browser OAuth OpenID Service
  • 200. Browser {...} OAuth OpenID Service
  • 201. Browser OAuth OpenID Service
  • 202. Browser OAuth OpenID Service {...} Login
  • 203.
  • 204. Browser OAuth OpenID Service
  • 205. Browser OAuth OpenID Service
  • 206. Browser OAuth OpenID Service
  • 207. Service or Desktop App OAuth OpenID Service
  • 208. Service or Desktop App OAuth OpenID Service
  • 209. Service or Desktop App {...} OAuth OpenID Service
  • 210. Service or Desktop App OAuth OpenID Service
  • 211. Service or Desktop App OAuth OpenID Service {...} Login
  • 212. curl -i http://localhost:9292/todos HTTP/1.1 401 Unauthorized Connection: close Date: Thu, 15 Jan 2009 22:24:23 GMT WWW-Authenticate: OAuth realm=quot;http://localhost:9292quot; Link: <http://localhost:9292/oauth/meta>; rel=quot;http://oauth.net/discovery/1.0/rel/providerquot; Content-Type: text/html Set-Cookie: rack.session=d6b1c6aa6d463a478eb9af0e921eb997; path=/; HttpOnly Content-Length: 1280 <!DOCTYPE html PUBLIC quot;-//W3C//DTD XHTML 1.0 Transitional//ENquot; quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtdquot;> <html xmlns=quot;http://www.w3.org/1999/xhtmlquot; xml:lang=quot;enquot; lang=quot;enquot;> ... etc ...
  • 213. $ curl -i http://localhost:9292/oauth/meta
  • 214. $ curl -i http://localhost:9292/oauth/meta <?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?> <XRD> <Type>http://oauth.net/discovery/1.0</Type> <Service> <Type>http://oauth.net/discovery/1.0/rel/provider</Type> <URI>http://localhost:9292/oauth</URI> </Service> </XRD>
  • 215. $ curl -i http://localhost:9292/oauth
  • 217. <?xml version=quot;1.0quot; encoding=quot;UTF-8quot;?> <XRDS xmlns=quot;xri://$xrdsquot;> <XRD xml:id=quot;oauthquot; xmlns:simple=quot;http://xrds-simple.net/core/1.0quot; xmlns=quot;xri://$XRD*($v*2.0)quot; version=quot;2.0quot;> <Type>xri://$xrds*simple</Type> <Expires>2009-02-14T22:27:50Z</Expires> <Service priority=quot;10quot;> <Type>http://oauth.net/core/1.0/endpoint/request</Type> <Type>http://oauth.net/core/1.0/parameters/auth-header</Type> <Type>http://oauth.net/core/1.0/parameters/uri-query</Type> <Type>http://oauth.net/core/1.0/signature/PLAINTEXT</Type> <URI>http://localhost:9292/oauth/request_tokens</URI> </Service> <Service priority=quot;10quot;> <Type>http://oauth.net/core/1.0/endpoint/authorize</Type> <Type>http://oauth.net/core/1.0/parameters/uri-query</Type> <URI>http://localhost:9292/oauth/authorization</URI> </Service> <Service priority=quot;10quot;> <Type>http://oauth.net/core/1.0/endpoint/access</Type> <Type>http://oauth.net/core/1.0/parameters/auth-header</Type> <Type>http://oauth.net/core/1.0/parameters/uri-query</Type> <Type>http://oauth.net/core/1.0/signature/PLAINTEXT</Type> <URI>http://localhost:9292/oauth/access_tokens</URI> </Service> <Service priority=quot;10quot;> <Type>http://oauth.net/core/1.0/endpoint/resource</Type> <Type>http://oauth.net/core/1.0/parameters/auth-header</Type> <Type>http://oauth.net/core/1.0/parameters/uri-query</Type> <Type>http://oauth.net/core/1.0/signature/HMAC-SHA1</Type> </Service> <Service priority=quot;10quot;> <Type>http://oauth.net/discovery/1.0/consumer-identity/static</Type> <LocalID>cloudkitconsumer</LocalID> </Service> </XRD> <XRD xmlns=quot;xri://$XRD*($v*2.0)quot; version=quot;2.0quot;> <Type>xri://$xrds*simple</Type> <Service priority=quot;10quot;> <Type>http://oauth.net/discovery/1.0</Type> <URI>#oauth</URI> </Service> </XRD> </XRDS>
  • 218. Service or Desktop App OAuth OpenID Service
  • 219. Service or Desktop App OAuth OpenID Service
  • 220. Service or Desktop App OAuth OpenID Service
  • 221. Service or Desktop App OAuth OpenID Service
  • 222. 1.0
  • 226. Done

Editor's Notes