Subject: [Jmap] Email/get after an Email/set with create

From: Mildred Ki'Lya <[email-masked]>
Date: Tue, 9 Nov 2021 23:39:53 +0100

Hello,

It seems I ran in a corner case in JMAP. I'm trying to get an Email 
object right after its creation. The reason is that I can then access 
fields generated by the server such as the Message-ID or other headers.

My JMAP request looks like:

       ['Email/set', {
         accountId: jMail.accountId,
         destroy: [ email.id ],
         create: {
           draft: {
             mailboxIds: {
               [mailboxId]: true
             },
             messageId: email.messageId,
             subject: subject,
             bodyStructure: {
               type: "text/plain",
               partId: "body"
             },
             bodyValues: {
               body: {
                 value: body,
                 isTruncated: false
               }
             }
           }
         }
       }, '1'],
       ['Email/get', {
         accountId: jMail.accountId,
         "#ids": { resultOf: "1", name: "Email/set", path: "/created/*/id" }
       }, '2']

Here, the Email/get request fails because the path (/created/*/id) is 
invalid. Indeed, "/created" represents a JSON object indexed by a 
temporary id ("draft" in my example). I see no way to get the Email 
object without another round-trip.

Can someone enlighten me if I missed something?

Thank you

---

From: "Neil Jenkins" <[email-masked]>
Date: Wed, 10 Nov 2021 13:37:20 +1100

Hi Mildred,

> Can someone enlighten me if I missed something?

No, you didn't miss anything. This currently requires two round trips. We tried to balance expressivity with simplicity and easy of implementation, and this is one of the things you can't currently express with the standard JMAP result ref syntax. If there were interest, it's something that could be added as an extension of course.

—Neil

---

From: "Robert Stepanek" <[email-masked]>
Date: Wed, 10 Nov 2021 08:54:51 +0100

On Wed, Nov 10, 2021, at 3:37 AM, Neil Jenkins wrote:
> No, you didn't miss anything. This currently requires two round trips. 

Just to note: the Cyrus IMAP [1] implementation of JMAP does allow to use creation ids in /get requests as a non-standard feature:

['Email/set', {
   create : {
     draft: {
       ...
     }
  },
}, '1'],
['Email/get', {
    ids: ['#draft'],
}, '2']

[1] https://www.cyrusimap.org/

---

From: Daniel Gultsch <[email-masked]>
Date: Wed, 10 Nov 2021 09:23:52 +0100

> No, you didn't miss anything. This currently requires two round trips.

Isn’t the set response supposed to return all server-set properties of
the email object?

cheers
Daniel

---

From: "Neil Jenkins" <[email-masked]>
Date: Wed, 10 Nov 2021 23:05:31 +1100

> Isn’t the set response supposed to return all server-set properties of

In general, yes. But the Email object is a bit unusual in that it's not the canonical underlying format (which is a RFC5322 message). Most properties are ways of asking the server to parse the message and return part of that data in a particular format. Therefore RFC8621 specifies exactly <https://datatracker.ietf.org/doc/html/rfc8621#section-4.6> what should be returned for create (which are all the properties not related to parsing the RFC5322 message):

   For successfully created Email objects, the "created" response
   contains the "id", "blobId", "threadId", and "size" properties of the
   object.

—Neil

---

From: [email-masked]
Date: Wed, 10 Nov 2021 22:57:14 +0100

Le 10/11/2021 à 03:37, Neil Jenkins a écrit :
> We tried to balance expressivity with simplicity and easy of 
> implementation, and this is one of the things you can't currently 
> express with the standard JMAP result ref syntax. If there were 
> interest, it's something that could be added as an extension of course.

Thank you for the details, I understand the need to keep the 
implementation simple but I would have imagined that a returned 
`createdIds` could have been returned for the sole purpose of chaining 
commands without needing to complexify the JSON path implementation. In 
any case, a round-trip is not really a problem (that's not there that I 
need the maximum performance), I just wanted to be sure that I did not 
miss something.

Mildred