Subject: [Jmap] back references

From: Josef 'Jeff' Sipek <[email-masked]>
Date: Thu, 7 Dec 2017 17:07:27 -0500

I had two thoughts related to back references.

1. As far as I can tell, the result of an action is always sent to the
   client.  That is, the value is sent even if the client doesn't actually
   care about the value and only does the action to provide a value via a
   back reference.  (This is different from IMAP's RETURN SAVE, which
   suppresses the transmission of the result to the client.)

   So, would it make sense to add a "suppress" field to the commands to
   avoid sending back data that is needed only for backrefs?

2. Currently, the use of a back reference is indicated by mangling the key
   name by prepending a '#'.  If the value produced is always an array,
   couldn't we use the *type* of the field (instead of the name) to indicate
   that it is a back reference?  E.g.,

    [[ "getFooUpdates", {
        "sinceState": "abcdef"
    }, "t0" ],
    [ "getFoos", {
        "ids": {
            "resultOf": "t0",
            "name": "fooUpdates",
            "path": "/changed"
        }
    }, "t1" ]]

   Normally, "ids" is supposed to be an array of strings but here we are given
   an object.  Therefore, we are dealing with a back reference.  Compare that
   to this example, where the "id"'s value is an array and therefore not a back
   reference.

    [[ "getFooUpdates", {
        "sinceState": "abcdef"
    }, "t0" ],
    [ "getFoos", {
        "ids": [ "f1", "f4" ]
    }, "t1" ]]

  This would work for most fields - certainly for all id fields.  The only
  place this breaks down is with "patch semantics" fields (e.g., keywords).
  With those, the value is supposed to be an object.  Is there a real use case
  of using back references to fill keywords or other patch semantics fields?
  If not, should we change back reference indication from the '#' prefix to a
  value type check?

Jeff.

-- 
All parts should go together without forcing.  You must remember that the
parts you are reassembling were disassembled by you.  Therefore, if you
can’t get them together again, there must be a reason.  By all means, do not
use a hammer.
		— IBM Manual, 1925

---

From: Neil Jenkins <[email-masked]>
Date: Fri, 08 Dec 2017 13:31:27 +1100

On Fri, 8 Dec 2017, at 09:07 AM, Josef 'Jeff' Sipek wrote:
>    client.
Correct. 

>   So, would it make sense to add a "suppress" field to the commands to>   avoid sending back data that is needed only for backrefs?

The overhead is not great, but on the other hand this is easy to
implement and does save a bit of unnecessary overhead. Implementation
wise you'd have to just strip the responses at the end, *after* making
all the method calls so that back references could resolve into them
correctly.
I guess this could either be an "omitResponse: Boolean" (or isSilent)
argument to each of the standard methods, or we come up with some
different way of attaching metadata to the method calls.
I'm not sure if this is worth it; anyone else got strong opinions on
whether we should add this?
> 2. Currently, the use of a back reference is indicated by mangling
>    the key>   name by prepending a '#'.  If the value produced is always an array,>   couldn't we use the **type** of the field (instead of the name) to
>   indicate>   that it is a back reference?

You could look at the type, and we considered this, but it's much easier
to implement in the current form, because you don't need to know the
type of the argument so a generic preprocessor can run to result the
back references before dispatching the method.
The back reference could resolve to any type, including an object (if
that's what this argument wanted). The current system just requires you
to loop through the argument names and look for a starting '#' then
replace this argument in a very straight-forward way. To do it based on
type, this preprocessor would have to be more tightly coupled to the
method being executed as it would need to know the exact types for each
of the arguments.
Neil.