FEP-a070: Ordered properties for plain JSON consumers

Hello!

This is a discussion thread for the proposed FEP-a070: Ordered properties for plain JSON consumers.
Please use this thread to discuss the proposed FEP and any potential problems
or improvements that can be addressed.

Summary

In a [Github-issue] filed against the normative AS2 context, it was pointed out that attachment and tag are unordered by default, although some implementations of “fediverse” software blindly assume them to always be ordered. This can be made unambiguous by using @list in JSON-LD, but for plain JSON consumers, a separate shorthand term must be defined. This FEP attempts to disambiguate between unordered and ordered arrays for those plain JSON consumers.

I think it would be useful to have some recommendations about how implementers would use these and the existing unordered properties without causing interoperability breaks, or at least reducing them.

For example, would early adopters wanting to publish ordered attachments going to need to provide both orderedAttachments and attachments for some period of time (possibly indefinitely), knowing that many implementations will be ignoring the orderedAttachments property?

If the publisher provides both, should a consumer consider the orderedAttachments as the primary collection and ignore the attachments collection (which could have different items if the publisher is doing something strange)? Also, in implementations that immediately serialize the JSON-LD to RDF (like Vocata) both collections will be stored in the graph unless there is some special preprocessing.

1 Like

it’s a bit of a messy situation, yeah… the migration path isn’t entirely clear.

i guess “option 3” is to redefine attachment and tag to be a @container: @list in the @context, which you’re not supposed to do generally. but consider it a willful violation. this effectively “opts in” to ordering for the document.

as discussed also, there is “option 2”, the possibility of upstreaming a normative change to the activitystreams.jsonld context, but this will break old documents that use a single value instead of an array. (if this happens, i’ll withdraw this FEP)

if going with “option 1” to have new terms using the same id as defined by this FEP, then i can see reasons to use both terms in plain JSON, but it is unclear when such a transitional period would end. in any case, you would use orderedAttachment if present and take it to be ordered, or if not present you would use attachment and assume unordered. (i’m not sure how LD handles the same property twice… i’ll play around with it in the playground)

and i suppose there is “option 0” as evan describes on the PR, which is to attach or tag a Collection or OrderedCollection, but this is semantically different than attaching or tagging items directly, and it would also be backwards-incompatible, as it effectively turns these into special collections similar to follower and following.

crossposted from Github

Generally, this question extends to the following properties in popular practice:

  • attachment (order of attachments sometimes matters)
  • tag (order of tags can matter, e.g. tumblr)
  • oneOf (order of poll options often matters)
  • anyOf (order of poll options often matters)

Per SocialHub discussion, our options are, from least messy migration to most messy migration:

  • 1: Manually override the term definition, per-document. This allows producers to opt into ordering for these properties, on a per-document basis. However, only LD-aware consumers will be able to tell the difference. (AS2 also forbids overriding AS2 terms, but consider this a willful violation.)

  • 2: Make normative changes, for everyone. This changes the AS2 context to align more closely to what most producers are already doing or assuming, essentially opting into (1) for everyone. However, some old documents might no longer be valid, if they contain a single item rather than an array.

  • 3: Use new orderedX properties. This removes the ambiguity completely, for both LD-aware and plain-JSON consumers; however, it requires plain-JSON consumers to check for the new orderedX properties, and this may result in producers duplicating information in both the unordered and ordered properties, which has unintended consequences for the LD representation.

For example, given the following:

{
  "@context": [
    "https://www.w3.org/ns/activitystreams",
    {
      "orderedAttachment": {
        "@id": "as:attachment",
        "@type": "@id",
        "@container": "@list"
       }
    }
  ],
  "orderedAttachment": ["one", "two"],
  "attachment": ["one", "two"]
}

It expands into the following:

[
  {
    "https://www.w3.org/ns/activitystreams#attachment": [
      {
        "@id": "one"
      },
      {
        "@id": "two"
      },
      {
        "@list": [
          {
            "@id": "one"
          },
          {
            "@id": "two"
          }
        ]
      }
    ]
  }
]

Compacting against only AS2 without the orderedAttachment extension results in this:

{
  "@context": "https://www.w3.org/ns/activitystreams",
  "attachment": [
    "one",
    "two",
    {
      "@list": [
        "one",
        "two"
      ]
    }
  ]
}
  • 4: Redefine these properties as collections. This allows the use of ordereditems. However, existing implementations will almost certainly be confused by this change. In some ways, this is a harder break than (3), but with cleaner results. Funnily enough, no changes are needed to the normative context, only to convention (although AS2-Vocab examples could be reworked).
{
  "@context": "https://www.w3.org/ns/activitystreams",
  "type": "Question",
  "name": "What is the answer?",
  "oneOf": {
    "type": "Collection",
    "orderedItems": [
      {
        "type": "Note",
        "name": "Option A"
      },
      {
        "type": "Note",
        "name": "Option B"
      }
    ]
  }
}

Option 5: using bits of semi-expanded LD within otherwise fully-compacted LD. Tangentially given option 3, we might say that instead of defining orderedX we can “simply” take the not-further-compactible @list notation and use it as-is.

Proposed solution: A single-item @set containing only a JSON-LD @list node, like so:

{
  "@context": "https://www.w3.org/ns/activitystreams",
  "attachment": {
    "@list": [
      "one",
      "two"
    ]
  }
}

Caveat as mentioned by Evan on Github: this is probably not expected, and it’s a bit weird, but otherwise “technically valid”.

The above 4 options still apply, with the previously discussed advantages and disadvantages.

One thing that might be worth exploring: Can we explicitly instead declare it to be an unordered set? I assume not, since @set is already the default) Indeed not, since @set compacts back to what we currently have, which is “assumed” to be ordered despite not actually being ordered.