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

A Glance At The Java Performance Toolbox
A Glance At The Java Performance ToolboxA Glance At The Java Performance Toolbox
A Glance At The Java Performance ToolboxAna-Maria Mihalceanu
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfNeo4j
 
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotesMuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotesManik S Magar
 
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...BookNet Canada
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch TuesdayIvanti
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
Landscape Catalogue 2024 Australia-1.pdf
Landscape Catalogue 2024 Australia-1.pdfLandscape Catalogue 2024 Australia-1.pdf
Landscape Catalogue 2024 Australia-1.pdfAarwolf Industries LLC
 
Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)Kaya Weers
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentPim van der Noll
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Farhan Tariq
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsRavi Sanghani
 
All These Sophisticated Attacks, Can We Really Detect Them - PDF
All These Sophisticated Attacks, Can We Really Detect Them - PDFAll These Sophisticated Attacks, Can We Really Detect Them - PDF
All These Sophisticated Attacks, Can We Really Detect Them - PDFMichael Gough
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 
React Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App FrameworkReact Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App FrameworkPixlogix Infotech
 
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...Jeffrey Haguewood
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersNicole Novielli
 
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfSo einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfpanagenda
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxLoriGlavin3
 

Recently uploaded (20)

A Glance At The Java Performance Toolbox
A Glance At The Java Performance ToolboxA Glance At The Java Performance Toolbox
A Glance At The Java Performance Toolbox
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdf
 
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotesMuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
 
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch Tuesday
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
Landscape Catalogue 2024 Australia-1.pdf
Landscape Catalogue 2024 Australia-1.pdfLandscape Catalogue 2024 Australia-1.pdf
Landscape Catalogue 2024 Australia-1.pdf
 
Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and Insights
 
All These Sophisticated Attacks, Can We Really Detect Them - PDF
All These Sophisticated Attacks, Can We Really Detect Them - PDFAll These Sophisticated Attacks, Can We Really Detect Them - PDF
All These Sophisticated Attacks, Can We Really Detect Them - PDF
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 
React Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App FrameworkReact Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App Framework
 
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software Developers
 
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfSo einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
 

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