SlideShare a Scribd company logo
+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
CloudKit
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
CloudKit
HTTP
Intermediaries



HTTP
Intermediaries   App



HTTP
Intermediaries   App



HTTP
Intermediaries   Rack



HTTP
CloudKit
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;);
CloudKit
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
CloudKit
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 ServiceMix
Bruce 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 you
Patrick 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 Ruby
Fabio 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
 
Celix universal OSGi
Celix universal OSGiCelix universal OSGi
Celix universal OSGi
OSGi User Group France
 
JSON Viewer XPATH Workbook
JSON Viewer XPATH WorkbookJSON Viewer XPATH Workbook
JSON Viewer XPATH Workbook
Suresh Krishna Madhuvarsu
 
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
Andy 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 surface
Saumil Shah
 
Socket applications
Socket applicationsSocket applications
Socket applications
João Moura
 
More Secrets of JavaScript Libraries
More Secrets of JavaScript LibrariesMore Secrets of JavaScript Libraries
More Secrets of JavaScript Libraries
jeresig
 
cdac@parag.gajbhiye@test123
cdac@parag.gajbhiye@test123cdac@parag.gajbhiye@test123
cdac@parag.gajbhiye@test123
Parag Gajbhiye
 
Beyond the Node: Arkestration with Noah
Beyond the Node: Arkestration with NoahBeyond the Node: Arkestration with Noah
Beyond the Node: Arkestration with Noah
lusis
 
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 Interactivity
Eric 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 2013
Amazon Web Services
 
Mobile web-debug
Mobile web-debugMobile web-debug
Mobile web-debug
FINN.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-Services
Ilya Grigorik
 
Enabling Microservices @Orbitz - Velocity Conf 2015
Enabling Microservices @Orbitz - Velocity Conf 2015Enabling Microservices @Orbitz - Velocity Conf 2015
Enabling Microservices @Orbitz - Velocity Conf 2015
Steve Hoffman
 
Web Application Defences
Web Application DefencesWeb Application Defences
Web Application Defences
Damilola Longe, CISSP, CCSP, MSc
 

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

find out more about the role of autonomous vehicles in facing global challenges
find out more about the role of autonomous vehicles in facing global challengesfind out more about the role of autonomous vehicles in facing global challenges
find out more about the role of autonomous vehicles in facing global challenges
huseindihon
 
20240704 QFM023 Engineering Leadership Reading List June 2024
20240704 QFM023 Engineering Leadership Reading List June 202420240704 QFM023 Engineering Leadership Reading List June 2024
20240704 QFM023 Engineering Leadership Reading List June 2024
Matthew Sinclair
 
BLOCKCHAIN FOR DUMMIES: GUIDEBOOK FOR ALL
BLOCKCHAIN FOR DUMMIES: GUIDEBOOK FOR ALLBLOCKCHAIN FOR DUMMIES: GUIDEBOOK FOR ALL
BLOCKCHAIN FOR DUMMIES: GUIDEBOOK FOR ALL
Liveplex
 
Scaling Connections in PostgreSQL Postgres Bangalore(PGBLR) Meetup-2 - Mydbops
Scaling Connections in PostgreSQL Postgres Bangalore(PGBLR) Meetup-2 - MydbopsScaling Connections in PostgreSQL Postgres Bangalore(PGBLR) Meetup-2 - Mydbops
Scaling Connections in PostgreSQL Postgres Bangalore(PGBLR) Meetup-2 - Mydbops
Mydbops
 
Understanding Insider Security Threats: Types, Examples, Effects, and Mitigat...
Understanding Insider Security Threats: Types, Examples, Effects, and Mitigat...Understanding Insider Security Threats: Types, Examples, Effects, and Mitigat...
Understanding Insider Security Threats: Types, Examples, Effects, and Mitigat...
Bert Blevins
 
What's New in Copilot for Microsoft365 May 2024.pptx
What's New in Copilot for Microsoft365 May 2024.pptxWhat's New in Copilot for Microsoft365 May 2024.pptx
What's New in Copilot for Microsoft365 May 2024.pptx
Stephanie Beckett
 
20240702 QFM021 Machine Intelligence Reading List June 2024
20240702 QFM021 Machine Intelligence Reading List June 202420240702 QFM021 Machine Intelligence Reading List June 2024
20240702 QFM021 Machine Intelligence Reading List June 2024
Matthew Sinclair
 
Quality Patents: Patents That Stand the Test of Time
Quality Patents: Patents That Stand the Test of TimeQuality Patents: Patents That Stand the Test of Time
Quality Patents: Patents That Stand the Test of Time
Aurora Consulting
 
Choose our Linux Web Hosting for a seamless and successful online presence
Choose our Linux Web Hosting for a seamless and successful online presenceChoose our Linux Web Hosting for a seamless and successful online presence
Choose our Linux Web Hosting for a seamless and successful online presence
rajancomputerfbd
 
Best Practices for Effectively Running dbt in Airflow.pdf
Best Practices for Effectively Running dbt in Airflow.pdfBest Practices for Effectively Running dbt in Airflow.pdf
Best Practices for Effectively Running dbt in Airflow.pdf
Tatiana Al-Chueyr
 
Implementations of Fused Deposition Modeling in real world
Implementations of Fused Deposition Modeling  in real worldImplementations of Fused Deposition Modeling  in real world
Implementations of Fused Deposition Modeling in real world
Emerging Tech
 
Details of description part II: Describing images in practice - Tech Forum 2024
Details of description part II: Describing images in practice - Tech Forum 2024Details of description part II: Describing images in practice - Tech Forum 2024
Details of description part II: Describing images in practice - Tech Forum 2024
BookNet Canada
 
Calgary MuleSoft Meetup APM and IDP .pptx
Calgary MuleSoft Meetup APM and IDP .pptxCalgary MuleSoft Meetup APM and IDP .pptx
Calgary MuleSoft Meetup APM and IDP .pptx
ishalveerrandhawa1
 
Manual | Product | Research Presentation
Manual | Product | Research PresentationManual | Product | Research Presentation
Manual | Product | Research Presentation
welrejdoall
 
Measuring the Impact of Network Latency at Twitter
Measuring the Impact of Network Latency at TwitterMeasuring the Impact of Network Latency at Twitter
Measuring the Impact of Network Latency at Twitter
ScyllaDB
 
DealBook of Ukraine: 2024 edition
DealBook of Ukraine: 2024 editionDealBook of Ukraine: 2024 edition
DealBook of Ukraine: 2024 edition
Yevgen Sysoyev
 
7 Most Powerful Solar Storms in the History of Earth.pdf
7 Most Powerful Solar Storms in the History of Earth.pdf7 Most Powerful Solar Storms in the History of Earth.pdf
7 Most Powerful Solar Storms in the History of Earth.pdf
Enterprise Wired
 
INDIAN AIR FORCE FIGHTER PLANES LIST.pdf
INDIAN AIR FORCE FIGHTER PLANES LIST.pdfINDIAN AIR FORCE FIGHTER PLANES LIST.pdf
INDIAN AIR FORCE FIGHTER PLANES LIST.pdf
jackson110191
 
Coordinate Systems in FME 101 - Webinar Slides
Coordinate Systems in FME 101 - Webinar SlidesCoordinate Systems in FME 101 - Webinar Slides
Coordinate Systems in FME 101 - Webinar Slides
Safe Software
 
Observability For You and Me with OpenTelemetry
Observability For You and Me with OpenTelemetryObservability For You and Me with OpenTelemetry
Observability For You and Me with OpenTelemetry
Eric D. Schabell
 

Recently uploaded (20)

find out more about the role of autonomous vehicles in facing global challenges
find out more about the role of autonomous vehicles in facing global challengesfind out more about the role of autonomous vehicles in facing global challenges
find out more about the role of autonomous vehicles in facing global challenges
 
20240704 QFM023 Engineering Leadership Reading List June 2024
20240704 QFM023 Engineering Leadership Reading List June 202420240704 QFM023 Engineering Leadership Reading List June 2024
20240704 QFM023 Engineering Leadership Reading List June 2024
 
BLOCKCHAIN FOR DUMMIES: GUIDEBOOK FOR ALL
BLOCKCHAIN FOR DUMMIES: GUIDEBOOK FOR ALLBLOCKCHAIN FOR DUMMIES: GUIDEBOOK FOR ALL
BLOCKCHAIN FOR DUMMIES: GUIDEBOOK FOR ALL
 
Scaling Connections in PostgreSQL Postgres Bangalore(PGBLR) Meetup-2 - Mydbops
Scaling Connections in PostgreSQL Postgres Bangalore(PGBLR) Meetup-2 - MydbopsScaling Connections in PostgreSQL Postgres Bangalore(PGBLR) Meetup-2 - Mydbops
Scaling Connections in PostgreSQL Postgres Bangalore(PGBLR) Meetup-2 - Mydbops
 
Understanding Insider Security Threats: Types, Examples, Effects, and Mitigat...
Understanding Insider Security Threats: Types, Examples, Effects, and Mitigat...Understanding Insider Security Threats: Types, Examples, Effects, and Mitigat...
Understanding Insider Security Threats: Types, Examples, Effects, and Mitigat...
 
What's New in Copilot for Microsoft365 May 2024.pptx
What's New in Copilot for Microsoft365 May 2024.pptxWhat's New in Copilot for Microsoft365 May 2024.pptx
What's New in Copilot for Microsoft365 May 2024.pptx
 
20240702 QFM021 Machine Intelligence Reading List June 2024
20240702 QFM021 Machine Intelligence Reading List June 202420240702 QFM021 Machine Intelligence Reading List June 2024
20240702 QFM021 Machine Intelligence Reading List June 2024
 
Quality Patents: Patents That Stand the Test of Time
Quality Patents: Patents That Stand the Test of TimeQuality Patents: Patents That Stand the Test of Time
Quality Patents: Patents That Stand the Test of Time
 
Choose our Linux Web Hosting for a seamless and successful online presence
Choose our Linux Web Hosting for a seamless and successful online presenceChoose our Linux Web Hosting for a seamless and successful online presence
Choose our Linux Web Hosting for a seamless and successful online presence
 
Best Practices for Effectively Running dbt in Airflow.pdf
Best Practices for Effectively Running dbt in Airflow.pdfBest Practices for Effectively Running dbt in Airflow.pdf
Best Practices for Effectively Running dbt in Airflow.pdf
 
Implementations of Fused Deposition Modeling in real world
Implementations of Fused Deposition Modeling  in real worldImplementations of Fused Deposition Modeling  in real world
Implementations of Fused Deposition Modeling in real world
 
Details of description part II: Describing images in practice - Tech Forum 2024
Details of description part II: Describing images in practice - Tech Forum 2024Details of description part II: Describing images in practice - Tech Forum 2024
Details of description part II: Describing images in practice - Tech Forum 2024
 
Calgary MuleSoft Meetup APM and IDP .pptx
Calgary MuleSoft Meetup APM and IDP .pptxCalgary MuleSoft Meetup APM and IDP .pptx
Calgary MuleSoft Meetup APM and IDP .pptx
 
Manual | Product | Research Presentation
Manual | Product | Research PresentationManual | Product | Research Presentation
Manual | Product | Research Presentation
 
Measuring the Impact of Network Latency at Twitter
Measuring the Impact of Network Latency at TwitterMeasuring the Impact of Network Latency at Twitter
Measuring the Impact of Network Latency at Twitter
 
DealBook of Ukraine: 2024 edition
DealBook of Ukraine: 2024 editionDealBook of Ukraine: 2024 edition
DealBook of Ukraine: 2024 edition
 
7 Most Powerful Solar Storms in the History of Earth.pdf
7 Most Powerful Solar Storms in the History of Earth.pdf7 Most Powerful Solar Storms in the History of Earth.pdf
7 Most Powerful Solar Storms in the History of Earth.pdf
 
INDIAN AIR FORCE FIGHTER PLANES LIST.pdf
INDIAN AIR FORCE FIGHTER PLANES LIST.pdfINDIAN AIR FORCE FIGHTER PLANES LIST.pdf
INDIAN AIR FORCE FIGHTER PLANES LIST.pdf
 
Coordinate Systems in FME 101 - Webinar Slides
Coordinate Systems in FME 101 - Webinar SlidesCoordinate Systems in FME 101 - Webinar Slides
Coordinate Systems in FME 101 - Webinar Slides
 
Observability For You and Me with OpenTelemetry
Observability For You and Me with OpenTelemetryObservability For You and Me with OpenTelemetry
Observability For You and Me with OpenTelemetry
 

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
  • 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
  • 38. HTTP
  • 40. Intermediaries App HTTP
  • 41. Intermediaries App HTTP
  • 42. Intermediaries Rack HTTP
  • 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 } });
  • 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
  • 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