blog

git clone https://git.ce9e.org/blog.git

commit
a11a556749c9d986ecd9ab56e730a5f991f3b633
parent
6b0680b6065a0903f7c5ab3437b5e715e4b9cf2e
Author
Tobias Bengfort <tobias.bengfort@posteo.de>
Date
2023-10-29 13:02
add post on JMAP Calendars

Diffstat

A _content/posts/2023-10-29-jmap-calendars/index.md 187 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
A _content/posts/2023-10-29-jmap-calendars/index.yml 3 +++

2 files changed, 190 insertions, 0 deletions


diff --git a/_content/posts/2023-10-29-jmap-calendars/index.md b/_content/posts/2023-10-29-jmap-calendars/index.md

@@ -0,0 +1,187 @@
   -1     1 # The old thing: CalDAV
   -1     2 
   -1     3 The predominant protocol used for syncing calendars is CalDAV
   -1     4 ([RFC 4791](https://www.rfc-editor.org/rfc/rfc4791)). CalDAV is a weird
   -1     5 protocol. It sends events in the iCalendar format
   -1     6 ([RFC 5545](https://www.rfc-editor.org/rfc/rfc5545)) over WebDAV
   -1     7 ([RFC 4918](https://www.rfc-editor.org/rfc/rfc4918)), which in turn is based on
   -1     8 XML and a modified version of HTTP. This is one example from the spec:
   -1     9 
   -1    10 ```
   -1    11 >> Request <<
   -1    12 
   -1    13 REPORT /bernard/work/ HTTP/1.1
   -1    14 Host: cal.example.com
   -1    15 Depth: 1
   -1    16 Content-Type: application/xml; charset="utf-8"
   -1    17 Content-Length: xxxx
   -1    18 
   -1    19 <?xml version="1.0" encoding="utf-8" ?>
   -1    20 <C:calendar-query xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">
   -1    21   <D:prop>
   -1    22     <C:calendar-data>
   -1    23       <C:limit-freebusy-set start="20060102T000000Z" end="20060103T000000Z"/>
   -1    24     </C:calendar-data>
   -1    25   </D:prop>
   -1    26   <C:filter>
   -1    27     <C:comp-filter name="VCALENDAR">
   -1    28       <C:comp-filter name="VFREEBUSY">
   -1    29         <C:time-range start="20060102T000000Z" end="20060103T000000Z"/>
   -1    30       </C:comp-filter>
   -1    31     </C:comp-filter>
   -1    32   </C:filter>
   -1    33 </C:calendar-query>
   -1    34 
   -1    35 >> Response <<
   -1    36 
   -1    37 HTTP/1.1 207 Multi-Status
   -1    38 Date: Sat, 11 Nov 2006 09:32:12 GMT
   -1    39 Content-Type: application/xml; charset="utf-8"
   -1    40 Content-Length: xxxx
   -1    41 
   -1    42 <?xml version="1.0" encoding="utf-8" ?>
   -1    43 <D:multistatus xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">
   -1    44   <D:response>
   -1    45     <D:href>http://cal.example.com/bernard/work/abcd8.ics</D:href>
   -1    46     <D:propstat>
   -1    47       <D:prop>
   -1    48         <D:getetag>"fffff-abcd8"</D:getetag>
   -1    49         <C:calendar-data>BEGIN:VCALENDAR
   -1    50 VERSION:2.0
   -1    51 PRODID:-//Example Corp.//CalDAV Client//EN
   -1    52 BEGIN:VFREEBUSY
   -1    53 ORGANIZER;CN="Bernard Desruisseaux":mailto:bernard@example.com
   -1    54 UID:76ef34-54a3d2@example.com
   -1    55 DTSTAMP:20050530T123421Z
   -1    56 DTSTART:20060101T100000Z
   -1    57 DTEND:20060108T100000Z
   -1    58 FREEBUSY;FBTYPE=BUSY-TENTATIVE:20060102T100000Z/20060102T120000Z
   -1    59 END:VFREEBUSY
   -1    60 END:VCALENDAR
   -1    61 </C:calendar-data>
   -1    62       </D:prop>
   -1    63       <D:status>HTTP/1.1 200 OK</D:status>
   -1    64     </D:propstat>
   -1    65   </D:response>
   -1    66 </D:multistatus>
   -1    67 ```
   -1    68 
   -1    69 Note how this uses the `REPORT` method, which is not part of stock HTTP. Also,
   -1    70 note how iCalendar is embedded in XML. It is certainly not impossible to parse
   -1    71 this, but it is far more complicated than it should be.
   -1    72 
   -1    73 The biggest issue with CalDAV is that it is not universally supported. For
   -1    74 example, [FullCalendar](https://fullcalendar.io), the go-to JavaScript
   -1    75 calendar, does not support CalDAV on its own. Since version 5.5 it does at
   -1    76 least allow to subscribe to read-only iCalendar feeds over HTTP though.
   -1    77 Microsoft products do the same. If you want to get proper read-write support to
   -1    78 your Microsoft calendars, you have to use their proprietary [Exchange
   -1    79 ActiveSync](https://en.wikipedia.org/wiki/Exchange_ActiveSync) protocol.
   -1    80 
   -1    81 I have recently worked with CalDAV and encountered two other issues:
   -1    82 
   -1    83 -   The events I worked with were all associated with an URL. iCalendar does
   -1    84     not offer an URL field, so users had to open the event, copy the URL from
   -1    85     the description field, and manually enter it into their browsers. This is
   -1    86     not a huge issue. Still, I believe this use case is common enough to
   -1    87     warrant a smoother user experience.
   -1    88 
   -1    89 -   There is no way for the server to notify clients of changes. Clients
   -1    90     typically pull for new events in regular intervals. This means that users
   -1    91     might make appointments in slots that are already taken because they work
   -1    92     with outdated data.
   -1    93 
   -1    94 Frustrated with all those issues, I started thinking about a new protocol that
   -1    95 could replace CalDAV. After a bit of research, I found that someone had already
   -1    96 done that work.
   -1    97 
   -1    98 # The new thing: JMAP Calendars
   -1    99 
   -1   100 [JMAP Calendars](https://jmap.io/spec-calendars.html) is a draft spec to send
   -1   101 events in JSCalendar format
   -1   102 ([RFC 8984](https://www.rfc-editor.org/rfc/rfc8984)) over JMAP
   -1   103 ([RFC 8620](https://www.rfc-editor.org/rfc/rfc8620)), which in turn is an
   -1   104 RPC protocol based on HTTP and JSON. Here is an example request from the spec:
   -1   105 
   -1   106 ```json
   -1   107 [
   -1   108   ["CalendarEvent/set", {
   -1   109     "accountId": "a0x9",
   -1   110     "create": {
   -1   111       "k559": {
   -1   112         "uid": "5d5776f6-ff8e-4bfd-ab3e-fe2fe5d4fa91",
   -1   113         "calendarIds": {
   -1   114           "3ddf2ad7-0e0c-4fb5-852d-f0ff56f3c662": true
   -1   115         },
   -1   116         "title": "Party at Pete’s",
   -1   117         "start": "2023-02-03T19:00:00",
   -1   118         "duration": "PT3H0M0S",
   -1   119         "timeZone": "Australia/Melbourne",
   -1   120         "showWithoutTime": false,
   -1   121         "participants": {
   -1   122           "1": {
   -1   123             "@type": "Participant",
   -1   124             "name": "Jane Doe"
   -1   125             "scheduleId": "mailto:jane@example.com",
   -1   126             "sendTo": {
   -1   127               "imip": "mailto:jane@example.com",
   -1   128               "other": "https://example.com/uri/for/internal/scheduling"
   -1   129             }
   -1   130             "kind": "individual",
   -1   131             "roles": {
   -1   132               "attendee": true,
   -1   133               "owner": true
   -1   134             },
   -1   135             "participationStatus": "accepted",
   -1   136             "expectReply": false
   -1   137           },
   -1   138           "2": {
   -1   139             "@type": "Participant",
   -1   140             "name": "Joe Bloggs",
   -1   141             "sendTo": {
   -1   142               "imip": "mailto:joe@example.com"
   -1   143             },
   -1   144             "kind": "individual",
   -1   145             "roles": {
   -1   146               "attendee": true
   -1   147             },
   -1   148             "participationStatus": "needs-action",
   -1   149             "expectReply": true
   -1   150           }
   -1   151         },
   -1   152         "mayInviteSelf": false,
   -1   153         "mayInviteOthers": false,
   -1   154         "useDefaultAlerts": false,
   -1   155         "alerts": null
   -1   156       }
   -1   157     },
   -1   158     "sendSchedulingMessages": true
   -1   159   }, "0"]
   -1   160 ]
   -1   161 ```
   -1   162 
   -1   163 This solves most of CalDAV problems:
   -1   164 
   -1   165 -   It is a much cleaner protocol. JMAP and JSCalendar both use JSON, so
   -1   166     parsing is simple. JMAP uses stock HTTP. I would have preferred it to be
   -1   167     more REST and less RPC, but that is something I can happily live with.
   -1   168 -   JSCalendar is based on the semantics of iCalendar, but also makes some
   -1   169     updates. For example, it adds a `Links` field and even a `virtualLocations`
   -1   170     field for online meetings.
   -1   171 -   JMAP has push support either via Server-sent events or external push
   -1   172     services.
   -1   173 
   -1   174 Of course, support for JMAP Calendars is currently even worse than it is for
   -1   175 CalDAV. To my knowledge, JMAP Calendars is not supported anywhere yet, and JMAP
   -1   176 in general hasn't seen much adoption either.
   -1   177 
   -1   178 On the other hand, HTTP and JSON are the de-facto standard for building APIs on
   -1   179 the web. With this clean protocol based on popular technologies, there is hope
   -1   180 that developers will add support once the spec stabilizes. I at least hope to
   -1   181 see a switch from iCalendar-over-HTTP to JSCalendar-over-HTTP.
   -1   182 
   -1   183 There are some other protocols (e.g. LDAP) that I would like to see replaced by
   -1   184 something based on HTTP and JSON. There are certainly many pros and cons to
   -1   185 this idea, not least of which is the difficulty for new protocols to gain
   -1   186 traction. Maybe JMAP Calendars can serve as a test to see if this is worth the
   -1   187 effort.

diff --git a/_content/posts/2023-10-29-jmap-calendars/index.yml b/_content/posts/2023-10-29-jmap-calendars/index.yml

@@ -0,0 +1,3 @@
   -1     1 title: JMAP for Calendars is awesome
   -1     2 date: 2023-10-29
   -1     3 tags: [code]