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

"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rick Flair
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningLars Bell
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxhariprasad279825
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
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
 
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
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demoHarshalMandlekar2
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
unit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxunit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxBkGupta21
 

Recently uploaded (20)

"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine Tuning
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptx
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
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
 
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
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demo
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
unit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxunit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.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