Introducing:

JSOP
Pitch & Goal
- Browser enabled, HTTP-based protocol
  designed to exchange fine-grained
  information efficiently.

- Easy to consume by todays
  Web-”Gear” (browsers, flash & friends)

- Probably suitable for an RFC @ IETF
Basics
- Serialization to JSON (optionally YAML/XML)
- GET (batch/hierarchical)
- PUT (batch/hierarchical)
- PATCH (json diff content type)
- Support for binary as multipart
Retro-style
- PUT & PATCH -> multipart POST
- Allows for Simple HTML forms
Extensions
- Sort-Order
- Query
- Typing
- Locking
- Versioning
- Essentially: WebDAV + friends but simple
Sample GET
Request:
GET /myfolder.json HTTP/1.1

Response:
{
"createdBy" : "uncled",
"name" : "myfolder",
"id" : "50d9317a-3a95-401a-9638-333a0dbf04bb"
"type" : "folder"
}
Sample GET 2
Request:
GET /myfolder.4.json HTTP/1.1

Response:
{
"createdBy" : "uncled",
"name" : "myfolder",
"id" : "50d9317a-3a95-401a-9638-333a0dbf04bb"
"type" : "folder"

"child1" :
  {
  "grandchild11" :
    {
    "depth3" :
      {
      "depth4 : { ... }
      }
    }
  }
}
Sample PUT
PUT /myfolder HTTP/1.1

{
"createdBy" : "uncled",
"name" : "myfolder",
"id" : "50d9317a-3a95-401a-9638-333a0dbf04bb"
"type" : "folder"

"child1" :
  {
  "grandchild11" :
    {
    "depth3" :
      {
      "depth4 : { ... }
      }
    }
  }
}
Sample PATCH
PATCH /myfolder HTTP/1.1

+newdoc : { "type" : "document", "createdBy" : "me" }
-olddoc
>movingdoc : /otherfolder/mydocument
^lastModifiedBy : "me"
PATCH diff ops
"+":
create Node/Property/Resource

"^":
update Node/Property/Resource

"-":
delete Node/Property/Resource

">":
move Node/Property/Resource
PATCH diff
diff       ::=   members
members    ::=   pair | pairs
pair       ::=   key [ " : " value ]
pairs      ::=   pair line-end pair | pair line-end pairs
line-end   ::=   "rn" | "n" | "r"
key        ::=   opchar id
opchar     ::=   "+" | "^" | "-" | ">"
id         ::=   * identification url (path | id) *
value      ::=   value+ | value- | value^ | value>
value+     ::=   * a JSON object *
value-     ::=   ""
value^     ::=   * any JSON value except JSON object *
value>     ::=   id
POST wrap 1
POST /myfolder/my.gif HTTP/1.1
Content-Type: multipart/form-data;
boundary=---------21447684891610979728262467120
Content-Length: 123

---------21447684891610979728262467120
Content-Disposition: form-data; name="data"
Content-Type: image/gif

GIF89a...................!.......,............s...f.;
---------21447684891610979728262467120
Content-Disposition: form-data; name="jsop:diff"
Content-Type: text/plain

^lastModifiedBy : "me"
+exif { cameraMake : "Apple", cameraModel : "Apple" }
---------21447684891610979728262467120--
POST wrap 2
POST /myfolder/my.gif HTTP/1.1
Content-Type: multipart/form-data;
boundary=---------21447684891610979728262467120
Content-Length: 123

---------21447684891610979728262467120
Content-Disposition: form-data; name="exif/cameraMake"
Content-Type: text/plain

Another Vendor
---------21447684891610979728262467120--
POST wrap 3
POST /myfolder/ HTTP/1.1
Content-Type: multipart/form-data;
boundary=---------21447684891610979728262467120
Content-Length: 123

---------21447684891610979728262467120
Content-Disposition: form-data; name=""; filename="my.gif"
Content-Type: image/gif

GIF89a...................!.......,............s...f.;
---------21447684891610979728262467120
Content-Disposition: form-data; name=""; filename="yo.gif"
Content-Type: image/gif

GIF89a...................!.......,............s...f.;
---------21447684891610979728262467120 --

JSOP in 60 seconds

  • 1.
  • 2.
    Pitch & Goal -Browser enabled, HTTP-based protocol designed to exchange fine-grained information efficiently. - Easy to consume by todays Web-”Gear” (browsers, flash & friends) - Probably suitable for an RFC @ IETF
  • 3.
    Basics - Serialization toJSON (optionally YAML/XML) - GET (batch/hierarchical) - PUT (batch/hierarchical) - PATCH (json diff content type) - Support for binary as multipart
  • 4.
    Retro-style - PUT &PATCH -> multipart POST - Allows for Simple HTML forms
  • 5.
    Extensions - Sort-Order - Query -Typing - Locking - Versioning - Essentially: WebDAV + friends but simple
  • 6.
    Sample GET Request: GET /myfolder.jsonHTTP/1.1 Response: { "createdBy" : "uncled", "name" : "myfolder", "id" : "50d9317a-3a95-401a-9638-333a0dbf04bb" "type" : "folder" }
  • 7.
    Sample GET 2 Request: GET/myfolder.4.json HTTP/1.1 Response: { "createdBy" : "uncled", "name" : "myfolder", "id" : "50d9317a-3a95-401a-9638-333a0dbf04bb" "type" : "folder" "child1" : { "grandchild11" : { "depth3" : { "depth4 : { ... } } } } }
  • 8.
    Sample PUT PUT /myfolderHTTP/1.1 { "createdBy" : "uncled", "name" : "myfolder", "id" : "50d9317a-3a95-401a-9638-333a0dbf04bb" "type" : "folder" "child1" : { "grandchild11" : { "depth3" : { "depth4 : { ... } } } } }
  • 9.
    Sample PATCH PATCH /myfolderHTTP/1.1 +newdoc : { "type" : "document", "createdBy" : "me" } -olddoc >movingdoc : /otherfolder/mydocument ^lastModifiedBy : "me"
  • 10.
    PATCH diff ops "+": createNode/Property/Resource "^": update Node/Property/Resource "-": delete Node/Property/Resource ">": move Node/Property/Resource
  • 11.
    PATCH diff diff ::= members members ::= pair | pairs pair ::= key [ " : " value ] pairs ::= pair line-end pair | pair line-end pairs line-end ::= "rn" | "n" | "r" key ::= opchar id opchar ::= "+" | "^" | "-" | ">" id ::= * identification url (path | id) * value ::= value+ | value- | value^ | value> value+ ::= * a JSON object * value- ::= "" value^ ::= * any JSON value except JSON object * value> ::= id
  • 12.
    POST wrap 1 POST/myfolder/my.gif HTTP/1.1 Content-Type: multipart/form-data; boundary=---------21447684891610979728262467120 Content-Length: 123 ---------21447684891610979728262467120 Content-Disposition: form-data; name="data" Content-Type: image/gif GIF89a...................!.......,............s...f.; ---------21447684891610979728262467120 Content-Disposition: form-data; name="jsop:diff" Content-Type: text/plain ^lastModifiedBy : "me" +exif { cameraMake : "Apple", cameraModel : "Apple" } ---------21447684891610979728262467120--
  • 13.
    POST wrap 2 POST/myfolder/my.gif HTTP/1.1 Content-Type: multipart/form-data; boundary=---------21447684891610979728262467120 Content-Length: 123 ---------21447684891610979728262467120 Content-Disposition: form-data; name="exif/cameraMake" Content-Type: text/plain Another Vendor ---------21447684891610979728262467120--
  • 14.
    POST wrap 3 POST/myfolder/ HTTP/1.1 Content-Type: multipart/form-data; boundary=---------21447684891610979728262467120 Content-Length: 123 ---------21447684891610979728262467120 Content-Disposition: form-data; name=""; filename="my.gif" Content-Type: image/gif GIF89a...................!.......,............s...f.; ---------21447684891610979728262467120 Content-Disposition: form-data; name=""; filename="yo.gif" Content-Type: image/gif GIF89a...................!.......,............s...f.; ---------21447684891610979728262467120 --