idnits 2.17.1 draft-toomim-httpbis-braid-http-02.txt: Checking boilerplate required by RFC 5378 and the IETF Trust (see https://trustee.ietf.org/license-info): ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/1id-guidelines.txt: ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/checklist : ---------------------------------------------------------------------------- No issues found here. Miscellaneous warnings: ---------------------------------------------------------------------------- == The copyright year in the IETF Trust and authors Copyright Line does not match the current year -- The document date (Mar 9, 2020) is 1508 days in the past. Is this intentional? Checking references for intended status: Proposed Standard ---------------------------------------------------------------------------- (See RFCs 3967 and 4897 for information about using normative references to lower-maturity documents in RFCs) == Unused Reference: 'RFC7230' is defined on line 732, but no explicit reference was found in the text == Unused Reference: 'RFC7231' is defined on line 734, but no explicit reference was found in the text == Unused Reference: 'RFC7233' is defined on line 736, but no explicit reference was found in the text == Unused Reference: 'RFC7234' is defined on line 738, but no explicit reference was found in the text ** Obsolete normative reference: RFC 7230 (Obsoleted by RFC 9110, RFC 9112) ** Obsolete normative reference: RFC 7231 (Obsoleted by RFC 9110) ** Obsolete normative reference: RFC 7233 (Obsoleted by RFC 9110) ** Obsolete normative reference: RFC 7234 (Obsoleted by RFC 9111) == Outdated reference: A later version (-19) exists of draft-ietf-httpbis-header-structure-14 -- Possible downref: Non-RFC (?) normative reference: ref. 'XHR' -- Possible downref: Non-RFC (?) normative reference: ref. 'SSE' -- Possible downref: Non-RFC (?) normative reference: ref. 'REST' ** Obsolete normative reference: RFC 3501 (Obsoleted by RFC 9051) Summary: 5 errors (**), 0 flaws (~~), 6 warnings (==), 4 comments (--). Run idnits with the --verbose option for more detailed information about the items above. -------------------------------------------------------------------------------- 1 Internet-Draft M. Toomim 2 Expires: Jul 10, 2020 Invisible College 3 Intended status: Proposed Standard G. Little 4 Invisible College 5 R. Walker 6 Bard College 7 B. Bellomy 8 Invisible College 9 Mar 9, 2020 11 \=/====\\ |//===\\= /=\ =\==\|\=/== =|====\== 12 ||/ |\\ ||\ |\\ /|| \|\ |// //| \\\ 13 |\\ |// |\\ |// //| \\\ \\\ /\/ ||| 14 \=|====|= |/====/=\ /=\/====|=\ =\= \\= =/= 15 //\ /\\ //| |\\ |/| ||| \\\ ||| |// 16 ||| ||| |\\ |// |\/ \|/ /|\ |=\ |\\ 17 =\=\==/=/ ==| |\= ||= /== ===/=|=\=== |==\===// 19 Braid-HTTP: Synchronization for HTTP 20 draft-toomim-httpbis-braid-http-02 22 Abstract 24 Braid is a set of extensions that generalize HTTP from a state 25 *transfer* protocol into a state *synchronization* protocol. Braid 26 puts the power of Operational Transform and CRDTs on the web, 27 improving network performance and enabling natively peer-to-peer, 28 collaboratively-editable, offline-first web applications. 30 Braid is composed of four extensions to HTTP: 32 1. VERSIONING on resources 33 2. SUBSCRIPTIONS on GET requests 34 3. PATCHES created from Range Requests 35 4. MERGE-TYPES that specify OT or CRDT behavior 37 These extensions are independent; each provides a distinct value for 38 a stand-alone use-case. However, when used together, they enable a 39 web resource to synchronize automatically across multiple clients, 40 servers and proxies, and support arbitrary simultaneous edits by 41 multiple writers, under arbitrary network delays and partitions, 42 while guaranteeing consistency using a OT, CRDT, or other algorithm. 44 These synchronization features provide a step towards a standard for 45 the dynamic internal state of websites. Web programmers currently 46 synchronize state across clients and servers with layers of 47 non-standard Javascript frameworks. A synchronization standard built 48 upon REST can enable programmers to read and write the internal state 49 of any website as easily as a local variable on their own site. This 50 could enable a separation of UI from state, and allow any user to 51 edit or choose their own UI for any website's state. 53 Status of this Memo 55 This Internet-Draft is submitted in full conformance with the 56 provisions of BCP 78 and BCP 79. 58 Internet-Drafts are working documents of the Internet Engineering 59 Task Force (IETF), its areas, and its working groups. Note that 60 other groups may also distribute working documents as 61 Internet-Drafts. The list of current Internet-Drafts is at 62 http://datatracker.ietf.org/drafts/current/. 64 Internet-Drafts are draft documents valid for a maximum of six months 65 and may be updated, replaced, or obsoleted by other documents at any 66 time. It is inappropriate to use Internet-Drafts as reference 67 material or to cite them other than as "work in progress." 69 The list of current Internet-Drafts can be accessed at 70 https://www.ietf.org/1id-abstracts.html 72 The list of Internet-Draft Shadow Directories can be accessed at 73 https://www.ietf.org/shadow.html 74 Table of Contents 76 1. Introduction ..................................................4 77 2. Versioning for Resources ......................................5 78 2.1. Comparison with ETag ........................................5 79 2.2. PUT a new version ...........................................6 80 2.3. PUT a new version as a patch ................................6 81 2.4. GET a specific version ......................................8 82 3. Subscriptions for GET .........................................9 83 3.1. Creating a Subscription ....................................11 84 3.2. Sending multiple updates per GET ...........................11 85 3.3. Continuing a Subscription ..................................12 86 3.4. Ending a Subscription ......................................12 87 3.5. Errors .....................................................12 88 4. Design Goals..................................................13 89 5. Use Cases ....................................................13 90 5.1. Dynamic Resources ..........................................13 91 5.2. Dynamic Proxies and Caches .................................14 92 5.3. A Serverless Chat Example ..................................14 93 6. Related Work .................................................15 94 6.1. Web Frameworks .............................................15 95 6.2. Existing IETF Standards ....................................16 96 7. IANA Considerations ..........................................16 97 7.1. Header Field Registration ..................................16 98 8. Security Considerations ......................................16 99 9. Conventions ..................................................16 100 10. Copyright Notice .............................................17 101 11. References ...................................................17 102 11.1. Normative References .......................................17 103 11.2. Informative References .....................................18 104 12. Acknowledgements .............................................19 105 13. Authors' Addresses ...........................................20 106 1. Introduction 108 HTTP transfers a static version of state within a single request and 109 response. If the state changes, HTTP does not automatically update 110 clients with the new versions. This design satisficed when webpages 111 were mostly static and written by hand; however today's websites are 112 dynamic, generated from layers of state in databases, and provide 113 realtime updates across multiple clients and servers. Programmers 114 today need to *synchronize*, not just *transfer* state, and to do 115 this, they must work around HTTP. 117 The web has a long history of these workarounds. The original web 118 required users to click reload when a page changed. XMLHTTPRequest 119 [XHR] made it possible to update just part of a page, running a GET 120 request behind the scenes. However, a GET request still could not 121 push updates. To work around this, web programmers would poll the 122 resource, which was inefficient. Long-polling was invented to 123 overcome the inefficiencies, which was standardized as Server-Sent 124 Events [SSE]. Yet, SSE provides semantics of an event-stream, not an 125 update-stream, and although a programmer can encode a protocol within 126 the event stream for updating a resource, there is still no standard 127 way to express the update of a resource. 129 In practice, web programmers today often give up on using standards 130 for "data that changes", and instead send custom messages over a 131 WebSocket -- a hand-rolled synchronization protocol. Unfortunately, 132 this forfeits the benefits of HTTP and ReST, such as caching, and a 133 uniform interface [REST]. As the web becomes increasingly dynamic, 134 web applications are forced to implement additional layers of 135 non-standard Javascript frameworks to synchronize changes to state. 137 Braid generalizes HTTP into a synchronization protocol, and ReST into 138 a synchronization architecture. It adds these features: 140 1. Versioning (Section 2) 142 Each resource has a history of changes, ordered in time. 144 2. Subscriptions (Section 3) 146 A Subscribe header can be added to GET requests, which promises 147 to push all future versions to the client, until the client says 148 forGET. 150 3. Range Patches [RANGE-PATCH] 152 Express changes to versions in patches, with a uniform format 153 based on Range Requests. 155 4. Merge Types [MERGE-TYPES] 157 If multiple clients and servers simultaneously edit the same 158 resource, they can guarantee a consistent resulting state by 159 implementing the same Merge Type. Resources specify their Merge 160 Type with a header. 162 Taken together, these features allow an arbitrary set of clients and 163 servers to make arbitrary edits to resources, under arbitrary network 164 delays and paritions, and merge all edits consistently, receiving 165 updates as soon as they reconnect. This enables caches to support 166 dynamic content, web applications to feature an offline mode, and 167 textareas to support collaborative editing. 169 2. Versioning for Resources 171 Each Braid resource has a current version, and a version history. 172 Versions are specified as a string in the [STRUCTURED-HEADERS] 173 format. Each version string must be unique, to differentiate any two 174 points in time. To specify the version of content in a request or 175 response body, a Version header MAY be included in a request for a 176 PUT, PATCH or POST, or in the response to a GET: 178 Version: "dkn7ov2vwg" 180 Every version has a set of Parents that denote the most recent parent 181 version(s) that were known at the time the version was created. The 182 full graph of parents forms a Directed Acyclic Graph (DAG), 183 representing the known partial order of all versions. A version A is 184 known to have occurred before a version B if and only if A is an 185 ancestor of B in the partial order. 187 Parents are also specified with a header in a PUT request or GET 188 response: 190 Parents: "ajtva12kid", "cmdpvkpll2" 192 The Parents header is a List of Strings, in the syntax of HTTP's 193 [STRUCTURED-HEADERS]. Each string is a version. For any two parent 194 versions A and B that are specified in a Parents header, A cannot be 195 a descendent of B or vice versa. The ordering of versions in the 196 list carries no meaning, and SHOULD be softed lexicographically. 198 If a client or server does not specify a Version for a resource it 199 transfers, the recipient MAY generate a new version ID of its own 200 choosing. If a client or server does not specify a Parents header 201 when transferring a new version, the recipient MAY presume that the 202 most recent versions it has seen are the parents of the new version. 204 2.1. Comparison with ETag 206 The Version header is similar to an ETag, but has two differences: 208 1. ETags are sensitive to Content-Encoding. If you send the same 209 version with a GZip Content-Encoding, it will have a different 210 ETag, but the same Version. 212 2. A Version marks a unique point in time -- not unique content. If 213 a resource is changed from version A to B, and then to C, such 214 that the contents at A are the same as the contents at C, then it 215 is possible versions A and C to have the same ETag, even though 216 they have different Versions. 218 2.2. PUT a new version 220 When a PUT request changes the state of a resource, it can specify 221 the new version of the resource, the parent versions that existed 222 when it was created, and the way multiple simultaneous changes should 223 be merged (the "Merge-Type"): 225 Request: 227 PUT /chat 228 Version: "ej4lhb9z78" | Version 229 Parents: "oakwn5b8qh", "uc9zwhw7mf" | 230 Content-Type: application/json | 231 Merge-Type: sync9 | 232 Content-Length: 73 | 233 | 234 [{text: "Hi, everyone!", | | Body 235 author: {type: "link", value: "/user/tommy"}}] | | 237 Response: 239 HTTP/1.1 200 OK 240 Patches: OK 242 Merge-Types are specified in [MERGE-TYPES]. The Version and Parents 243 headers are optional. If Version is omitted, the recipient may 244 invent a version ID. If Parents is omitted, the recipient may assume 245 that the current set of leaf versions on its machine is the version's 246 context. 248 This example includes the entire new value of the state, but one can 249 also send updates as patches. 251 2.3. PUT a new version as a patch 253 Not only are patches smaller, and thus more efficient; they also 254 provide useful information for merging two simultaneous edits, for 255 instance in collaborative editing. 257 One can send an update in a patch by setting the "Patches" header to 258 a number, and then set the Message body to a sequence of that many 259 patches, separated by blank lines: 261 Request: 263 PUT /chat 264 Version: "g09ur8z74r" | Version 265 Parents: "ej4lhb9z78" | 266 Content-Type: application/json | 267 Merge-Type: sync9 | 268 Patches: 2 | 269 | 270 Content-Length: 62 | | Patch 271 Content-Range: json .messages[1:1] | | 272 | | 273 [{text: "Yo!", | | 274 author: {type: "link", value: "/user/yobot"}] | | 275 | 276 Content-Length: 40 | | Patch 277 Content-Range: json .latest_change | | 278 | | 279 {"type": "date", "value": 1573952202370} | | 281 Response: 283 HTTP/1.1 200 OK 284 Patches: OK 286 In order to distinguish each patch within a Version, we need to know 287 the length of the patch. To know the length of the patch, each patch 288 must include one of the following headers: 290 Content-Length: N 291 Transfer-Encoding: chunked 293 Either of these provide a way to determine when the next message 294 starts. 296 The previous example uses the Range Patch format, which is defined in 297 [RANGE-PATCH]. However, one can use any patch format, by sending a 298 patch with a Content-Type: set to a patch format with a defined 299 behavior, such as application/json-patch+json (as specified in 300 [RFC6902]): 302 Request: 304 PUT /chat 305 Version: "up12vyc5ib" | Version 306 Parents: "2bcbi84nsp" | 307 Content-Type: application/json | 308 Merge-Type: sync9 | 309 Patches: 1 | 310 | 311 Content-Length: 326 | | Patch 312 Content-Type: application/json-patch+json | | 313 | | 314 [ | | 315 { "op": "test", "path": "/a/b/c", "value": "foo" }, | | 316 { "op": "remove", "path": "/a/b/c" }, | | 317 { "op": "add", "path": "/a/b/c", "value": [] }, | | 318 { "op": "replace", "path": "/a/b/c", "value": 42 }, | | 319 { "op": "move", "from": "/a/b", "path": "/a/d }, | | 320 { "op": "copy", "from": "/a/d/d", "path": "/a/d/e" }| | 321 ] | | 323 Response: 325 HTTP/1.1 200 OK 326 Patches: OK 327 2.4. GET a specific version 329 A server can optionally allow clients to request historical versions 330 of a resource in GET requests. To request a historical version, a 331 client includes a Version and/or Parents header in the request. 333 Request: 335 GET /chat 336 Version: "ej4lhb9z78" 338 Response: 340 HTTP/1.1 209 Subscription 341 Subscribe: keep-alive 343 Version: "ej4lhb9z78" | Version 344 Parents: "oakwn5b8qh", "uc9zwhw7mf" | 345 Content-Type: application/json | 346 Merge-Type: sync9 | 347 Content-Length: 73 | 348 | 349 [{text: "Hi, everyone!", | | Body 350 author: {type: "link", value: "/user/tommy"}}] | | 352 If a GET request contains a Version header: 354 - The Subscribe header (Section 3) MUST be absent. 356 - The server SHOULD return a single response, containing that 357 version of the resource in its body, with the Version header set 358 to the version requested by the client. 360 - If the server does not support historical versions, it MAY ignore 361 the Version header and respond as usual, but MUST NOT include the 362 Version header in its response. 364 If a GET request contains a Parents header: 366 - If the request does not also contain a Version, then the request 367 MUST also contain a Subscribe header, and the server SHOULD send 368 a set of versions connecting the Parents to the current Version, 369 and then subscribe the client to future updates. 371 - If the request also contains a Version, then the server SHOULD 372 respond with a set of versions that connect the specified Parents 373 with the specified Version, and then close the connection. 375 - If the server does not support historical versions, then it MAY 376 ignore the Parents header, but MUST NOT include the Parents 377 header in its response. 379 A server MAY refactor or rebase the version history that it provides 380 to a client, so long as it does not affect the resulting state, or 381 the result of the patch-type's merges. 383 3. Subscriptions for GET 385 If a GET request includes the Subscribe header, it will return a 386 stream of versions; a new version pushed with each change. Each 387 version can contain either the new contents in its body, or a set of 388 Patches. 390 Request: 392 GET /chat 393 Subscribe: keep-alive 395 Response: 397 HTTP/1.1 209 Subscription 398 Subscribe: keep-alive 400 Version: "ej4lhb9z78" | Version 401 Parents: "oakwn5b8qh", "uc9zwhw7mf" | 402 Content-Type: application/json | 403 Merge-Type: sync9 | 404 Content-Length: 73 | 405 | 406 [{text: "Hi, everyone!", | | Body 407 author: {type: "link", value: "/user/tommy"}}] | | 409 Version: "g09ur8z74r" | Version 410 Parents: "ej4lhb9z78" | 411 Content-Type: application/json | 412 Merge-Type: sync9 | 413 Patches: 1 | 414 | 415 Content-Length: 62 | | Patch 416 Content-Range: json .messages[1:1] | | 417 | | 418 [{text: "Yo!", | | 419 author: {type: "link", value: "/user/yobot"}] | | 421 Version: "2bcbi84nsp" | Version 422 Parents: "g09ur8z74r" | 423 Content-Type: application/json | 424 Merge-Type: sync9 | 425 Patches: 1 | 426 | 427 Content-Length: 68 | | Patch 428 Content-Range: json .messages[2:2] | | 429 | | 430 [{text: "Hi, Tommy!", | | 431 author: {type: "link", value: "/user/sal"}}] | | 432 Version: "up12vyc5ib" | Version 433 Parents: "2bcbi84nsp" | 434 Content-Type: application/json | 435 Merge-Type: sync9 | 436 Patches: 1 | 437 | 438 Content-Length: 326 | | Patch 439 Content-Type: application/json-patch+json | | 440 | | 441 [ | | 442 { "op": "test", "path": "/a/b/c", "value": "foo" }, | | 443 { "op": "remove", "path": "/a/b/c" }, | | 444 { "op": "add", "path": "/a/b/c", "value": [] }, | | 445 { "op": "replace", "path": "/a/b/c", "value": 42 }, | | 446 { "op": "move", "from": "/a/b", "path": "/a/d }, | | 447 { "op": "copy", "from": "/a/d/d", "path": "/a/d/e" }| | 448 ] | | 449 3.1. Creating a Subscription 451 The "Subscribe" header on a GET request modifies the method semantics 452 to request a subscription to future updates to the data, rather than 453 only the current version of the representation data. 455 A client requests a subscription by issuing a GET request with a 456 Subscribe header: 458 Subscribe 459 or Subscribe: keep-alive 460 or Subscribe: keep-alive= 462 If a server implements Subscribe, it MUST include a Subscribe header 463 in its response. The server then SHOULD keep the connection open, 464 and send updates over it. 466 In general, a server that implements subscriptions promises to keep 467 its subscribed clients up-to-date by sending changes until the client 468 closes the subscription. A subscription is different from a GET 469 connection (e.g. a TCP connection, or HTTP/2 stream). If a client 470 requests "Subscribe: keep-alive", then the subscription will be 471 remembered even after the GET connection closes. A subscription can 472 be resumed by the client issuing another GET with a Subscribe header. 474 3.2. Sending multiple updates per GET 476 To send multiple updates, a server concatenates multiple 477 sub-responses into a single response body. Each sub-response must 478 contain its own headers and body. Each sub-response must have a 479 known length, which means it must contain one of the following 480 headers: 482 - Content-Length: N 483 - Transfer-Encoding: chunked 484 - Patches: N 486 Each sub-response must have both headers and a body. The body may be 487 zero-length. 489 3.3. Continuing a Subscription 491 Even if a connection closes, a subscription might still be active. 492 If a server's response headers for a connection contained: 494 Subscribe: keep-alive 495 or Subscribe: keep-alive= 497 Then the server SHOULD keep the subscription open even after the 498 connection closes. This means that the server promises to keep 499 enough history to merge with the client when the client comes back 500 online. 502 When the client reconnects, it may specify the most recent versions 503 it saw from the server using the Parents header. This tells the 504 server which versions of state to catch it up from. 506 The server can suggest how long it will wait for the client by 507 responding with Subscribe: keep-alive=. A server should 508 wait at least after a connection closes before dropping the 509 subscription, and clearing its history. 511 3.4. Ending a Subscription 513 Servers and clients MAY drop a subscription at any time, no matter 514 the value of keep-alive. A client may reconnect by issuing a new GET 515 request with a new Subscribe header. 517 If a subscription is set to keep-alive, then closing the TCP/QUIC 518 connection won't end the subscription. Thus a client needs a way to 519 explicitly end the subscription. In HTTP/1, this is by sending the 520 text "forGET\n" over the TCP connection. In HTTP/2, this is by 521 issuing a CLOSE event to the GET request's stream. Alternatively, 522 since today's web browsers do not support sending extra text after a 523 request body, the client can issue a fresh request specified as a 524 FORGET method. 526 3.5. Errors 528 If a server has dropped the history that a client requests, the 529 server can return a 410 GONE response, to tell the client "sorry, I 530 don't have the history necessary to synchronize with you." 531 4. Design Goals 533 This spec is designed to be: 535 1. Backwards-compatible with existing HTTP 537 2. Easy to implement simple synchronizers with. For instance, it 538 should be easy to write a read-only synchronizer for an 539 append-only log. 541 3. Possible to implement arbitrary synchronization algorithms. For 542 instance, these extensions support any Operational Transform or 543 CRDT algorithm. 545 5. Use Cases 547 5.1. Dynamic Resources: Animating a GIF 549 Braid allows resources to become inherently dynamic -- able to change 550 over time. You can use this to make a resource animate. 552 In this example, a server streams changes to a GIF file in a sequence 553 of patches. When the client renders the new state of the GIF after 554 each patch, a new frame of animation is displayed. 556 Request: 557 GET /animated-braid.gif 558 Subscribe 560 Response: 561 HTTP/1.1 209 Subscribe 562 Content-Type: image/gif | Version 563 Patches: 2 | 564 | 565 Content-Length: 1239 | | Patch 566 Content-Range: bytes 100-200 | | 567 | | 568 | | 569 | 570 Content-Length: 62638 | | Patch 571 Content-Range: bytes 348-887 | | 572 | | 573 | | 574 5.2. Dynamic Proxies and Caches 576 Since updates aren't pushed, today's web often uses timeouts to 577 trigger a cache becoming stale. Unfortunately, sometimes the timeout 578 is wrong, and caches become out-of-date, and we have to wait for an 579 unknown cache to timeout before we can see the new version of 580 something. As a result, programmers have learned to force-reload 581 pages habitually, and caches become less efficient than necessary. 583 A cache supporting the Braid extensions, however, will automatically 584 update whenever a change occurs. If a client starts a GET 585 Subscription with a proxy, the proxy will then start and maintain a 586 GET Subscription with the origin server. The origin server will 587 promise to send the proxy updates over its GET Subscription, and the 588 proxy will then relay these changes to all connected clients. If a 589 set of clients and servers all support Braid, they will never need to 590 force-reload caches for any data amongst them. 592 5.3. A Serverless Chat Example 594 A Braid web application can operate offline. A user can use the app 595 from an airplane, and their edits can synchronize when they regain 596 internet connections. Additionally, the Braid protocol can be 597 expressed over peer-to-peer transports (e.g. Braid-WebRTC) to support 598 a peer-to-peer synchronization without a server. Braid-HTTP clients 599 will be able to interoperate with Braid-WebRTC peers. For example, a 600 chat application might be served and synchronized on Braid-HTTP, 601 while also establishing redundant peer-to-peer connections on 602 Braid-WebRTC. The server could then be shut down, and users of the 603 chat app could continue to send messages to one another. 605 Imagine the server serves the current set of trusted clients' IP 606 addresses at the /peers state. Each client then subscribes to the 607 /peers state with: 609 GET /peers 610 Subscribe: keep-alive 611 ------- 612 [ {ip: '13.55.32.158', pubkey: 'x371...8382'}, 613 {ip: '244.38.55.83', pubkey: 'o2u8...2s73'}, 614 ... 615 ] 617 Each peer can then choose a set of those peers with whom to establish 618 a WebRTC connection. It will then exchange Braid messages with those 619 peers over that connection. 621 6. Related Work 623 6.1. Web Frameworks 625 Web applications typically synchronize the state of a client and 626 server with layers of models, views, and controllers in web 627 frameworks. By automating synchronization within HTTP, programmers 628 have to write fewer layers of code on top of it. 630 ====== Legacy Websites ====== ====== Braid Websites ====== 632 Today's webpages are Braid generalizes HTTP 633 generated from multiple into a standard for 634 layers of state. Each layer synchronizing state within 635 has a different API. and between websites. 637 x Non-standard state API o Standard state API 639 _Client__ 640 / \ 641 : o o o o : Webpage DOM o o o o State 642 : \| \| : \| \| 643 : x x : HTML Templates o o State 644 : /| /| : /| /| 645 : x x x x : JS Models o o o o State 646 \ | | | | / | | | | 647 | | | | | | | | 648 o o o o - http:// - o o o o - http:// - 649 / | | | | \ | | | | 650 : x x x x : Views o o o o State 651 : | \| | : | \| | 652 : x x x : Controllers o o o State 653 : \ / \| : \ / \| 654 : x x : Models o o State 655 : \ / : \ / 656 \.... x ../ Database o State 657 Server 659 Today's programmers have to Each piece of Braid state (o) 660 learn each API, and wire them has a URL; whether public or 661 together, making sure that internal. State can be a 662 changes to shared state function of other state, and 663 synchronize across all and automatically recompute 664 layers and computers. when its dependencies change. 665 Braid guarantees network 666 synchronization. 668 6.2. Existing IETF Standards 670 A number of IETF specifications already standardize aspects of 671 synchronization for specific domains. IMAP [RFC3501] provides 672 synchronization of email. WebDAV provides the synchronization of 673 "collections" [RFC6578], and has been extended specifically for 674 calendar data in CalDAV [RFC4791], and vCards in [RFC6350]. More 675 recently, JMAP [RFC8620] provides an updated method of 676 synchronization, supporting mail, calendars, and contacts. 678 7. IANA Considerations 680 7.1. Header Field Registration 682 HTTP header fields are registered within the "Message Headers" 683 registry maintained at 684 . 686 This document defines the following HTTP header fields, so their 687 associated registry entries have been updated according to the 688 permanent registrations below (see [BCP90]): 690 +---------------------+----------+--------------+-------------+ 691 | Header Field Name | Protocol | Status | Reference | 692 +---------------------+----------+--------------+-------------+ 693 | Version | http | experimental | Section 2 | 694 | Parents | http | experimental | Section 2 | 695 | Merge-Type | http | experimental | Section 2.2 | 696 | Patches | http | experimental | Section 2.3 | 697 | Subscribe | http | experimental | Section 4 | 698 +---------------------+----------+--------------+-------------+ 700 The change controller is: "IETF (iesg@ietf.org) - Internet 701 Engineering Task Force". 703 8. Security Considerations 705 XXX Todo 707 9. Conventions 709 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 710 "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this 711 document are to be interpreted as described in [RFC2119]. 713 10. Copyright Notice 715 Copyright (c) 2020 IETF Trust and the persons identified as the 716 document authors. All rights reserved. 718 This document is subject to BCP 78 and the IETF Trust's Legal 719 Provisions Relating to IETF Documents 720 (http://trustee.ietf.org/license-info) in effect on the date of 721 publication of this document. Please review these documents 722 carefully, as they describe your rights and restrictions with respect 723 to this document. Code Components extracted from this document must 724 include Simplified BSD License text as described in Section 4.e of 725 the Trust Legal Provisions and are provided without warranty as 726 described in the Simplified BSD License. 728 11. References 730 11.1. Normative References 732 [RFC7230] "HTTP/1.1 Message Syntax and Routing", RFC 7230. 734 [RFC7231] "HTTP/1.1 Semantics and Content", RFC 7231. 736 [RFC7233] "HTTP/1.2 Range Requests", RFC 7233. 738 [RFC7234] "HTTP/1.2 Caching", RFC 7234. 740 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 741 Requirement Levels", BCP 14, RFC 2119, March 1997. 743 [MERGE-TYPES] draft-toomim-httpbis-merge-types-00 745 [RANGE-PATCH] draft-toomim-httpbis-range-patch-00 747 [STRUCTURED-HEADERS] draft-ietf-httpbis-header-structure-14 748 11.2. Informative References 750 [XHR] Van Kestern, A., Aubourg, J., Song, J., and R. M. 751 Steen, H. "XMLHttpRequest", September 2019. 752 754 [SSE] Hickson, I. "Server-Sent Events", W3C Recommendation, 755 February 2015. 756 758 [REST] Fielding, R. "Architectural Styles and the Design of 759 Network-based Software Architectures" Doctoral 760 dissertation, University of California, Irvine, 2000. 762 [RFC3501] Crispin, M., "Internet Message Access Protocol - Version 763 4rev1", RFC 3501, DOI 10.17487/RFC3501, March 2003, 764 . 766 [RFC6578] Daboo, C., Quillaud, A., "Collection Synchronization 767 for Web Distributed Authoring and Versioning (WebDAV)", 768 RFC 6578, DOI 10.17487/RFC6578, March 2012, 769 . 771 [RFC4791] Daboo, C., Desruisseaux, B., Dusseault, L., "Calendaring 772 Extensions to WebDAV (CalDAV)", RFC 4791, 773 DOI 10.17487/RFC4791, March 2007, 774 . 776 [RFC6350] Perreault, S., "vCard Format Specification", RFC 6350, 777 DOI 10.17487/RFC6350, August 2011, 778 . 780 [RFC8620] Jenkins, N., Newman, C., "The JSON Meta Application 781 Protocol (JMAP)", RFC 8620, DOI 10.17487/RFC8620, 782 July 2019, . 784 [RFC6902] Bryan, P., Nottingham, M., "Javascript Object Notation 785 (JSON) Patch", RFC 6902. 787 [BCP90] Klyne, G., Nottingham, M., and J. Mogul, "Registration 788 Procedures for Message Header Fields", BCP 90, RFC 3864, 789 September 2004. 791 12. Acknowledgements 793 In addition to the authors, this spec contains intellectual 794 contributions from the following people: 796 - Seph Gentle 797 - Mitar Milutinovic 798 - Sarah Allen 799 - Duane Johnson 800 - Travis Kriplean 801 - Marius Nita 802 - Paul Pham 803 - Morgan Dixon 804 - Karthik Palaniappan 806 We thank the following people for key feedback on previous drafts: 808 - Austin Wright 809 - Martin Thomson 810 - Eric Kinnear 811 - Olli Vanhoja 812 - Julian Reschke 814 We also thank Mark Nottingham, Fred Baker, Adam Roach, and Barry 815 Leiba for facilitating a productive environment. 817 13. Authors' Addresses 819 For more information, the authors of this document are best contacted 820 via Internet mail: 822 Michael Toomim 823 Invisible College, Berkeley 824 2053 Berkeley Way 825 Berkeley, CA 94704 827 EMail: toomim@gmail.com 828 Web: https://invisible.college/@toomim 830 Greg Little 831 Invisible College, Berkeley 832 2053 Berkeley Way 833 Berkeley, CA 94704 835 EMail: glittle@gmail.com 836 Web: https://glittle.org/ 838 Rafie Walker 839 Bard College 841 EMail: slickytail.mc@gmail.com 843 Bryn Bellomy 844 Invisible College, Berkeley 845 2053 Berkeley Way 846 Berkeley, CA 94704 848 EMail: bryn@signals.io 849 Web: https://invisible.college/@bryn