w3c / activitystreams

Activity Streams 2.0
https://www.w3.org/TR/activitystreams-core/
Other
279 stars 61 forks source link

Remove 'CollectionPage' from Range of `next` and `prev` #449

Closed cjslep closed 6 years ago

cjslep commented 6 years ago

Please Indicate One:

Please Describe the Issue:

I am not sure why the specification permits putting a CollectionPage within a CollectionPage. Just let it remain Link and, via JSON-LD, an IRI. The following is compliant with the spec:

{
  "@context": "https://www.w3.org/ns/activitystreams",
  "summary": "Page 1 of Sally's blog posts",
  "type": "CollectionPage",
  "next": {
    "summary": "Page 2 of Sally's blog posts",
    "type": "CollectionPage",
    "next": {
      "summary": "Page 3 of Sally's blog posts",
      "type": "CollectionPage",
      "next": "http://example.org/collection?page=4",
      "items": [
        "http://example.org/posts/7",
        "http://example.org/posts/8",
        "http://example.org/posts/9"
      ]
    },
    "items": [
      "http://example.org/posts/4",
      "http://example.org/posts/5",
      "http://example.org/posts/6"
    ]
  },
  "items": [
    "http://example.org/posts/1",
    "http://example.org/posts/2",
    "http://example.org/posts/3"
  ]
}

It's turtles all the way down.

gobengo commented 6 years ago

I have some utility functions that take in an IRI-full ActivityStreams object, and down to a maximum nesting level, resolves all those IRIs into nested objects like your valid example above. Why make them invalid?

e.g. I do this a lot in a 'Controller'-type object of a webapp to prepare a single AS object to hand to the templating engine. It pre-fetches all those IRIs and embed subobjects so the 'View' layer doesn't have to. The View layer is "just a function that takes an AS object and returns HTML".

I fear if we disallowed CollectionPage in the range of next, it require me say "okay well actually the VIew layer doesn't take AS objects. It takes objects that are almost... like AS objects but where properties whose range is only Link are allowed to be whatever the Link might resolve to". Not very elegant. Just sharing a real-world place where code I've written would usefully create something like your example above.

cjslep commented 6 years ago

I see, this is probably one of those JSON-LD processing algorithms (expansion).

When delivering to recipients in ActivityPub, implementations are required to iterate through a collection if it was a target, and resolve those URIs. It is a painful experience in a statically typed language like golang to be able to handle both the iterative and recursive use cases at the same time. And from other specs that build on top of ActivityStream (such as ActivityPub) this kind of detail can be easily missed and cause implementations to not federate correctly with one another.

Also, I don't really understand this bit:

I fear if we disallowed CollectionPage in the range of next, it require me say "okay well actually the VIew layer doesn't take AS objects. It takes objects that are almost... like AS objects but where properties whose range is only Link are allowed to be whatever the Link might resolve to". Not very elegant.

Such a View would take ActivityStream objects. Nothing about my proposal puts it at odds with the Object base type from which everything else is inheriting from. CollectionPage would still be an ActivityStream object. So I am not really understanding what the point is here, unless it is a fight over the meaning of words (which I would like to avoid).

However, your pointing out of the IRI expansion bit made me realize my original proposal most likely breaks compatibility with JSON-LD and therefore is a no-go from the start.

As an aside, it is just making me realize that the ActivityStream spec (and perhaps JSON-LD) is perhaps too overly-focused on dynamically typed languages such as Javascript, and did not spend much time thinking about the consequences of implementations trying to use a statically-typed value wrapping the given type.

gobengo commented 6 years ago

Also, I don't really understand this bit:

I just meant that right now I have a typed function that often takes objects that look like your example (value of 'next' is a CollectionPage, not just an IRI). I read your original post has proposing constraining the range of the next property down from Object to just Link, which would make that sort of object no longer a valid AS Object (because it contains a next property whose value is an object), meaning I'd have to go invent a slightly different type to allow next to be a CollectionPage.

I guess that's just another way of saying your proposal (as I read it, which could be mistaken) is not backward-compatible.

As an aside, it is just making me realize that the ActivityStream spec (and perhaps JSON-LD) is perhaps too overly-focused on dynamically typed languages such as Javascript, and did not spend much time thinking about the consequences of implementations trying to use a statically-typed value wrapping the given type.

fair enough. Wish I had more hands-on golang experience to see how/if I would approach this. When I get better at golang, I'll take a stab at it.

cjslep commented 6 years ago

Gotcha. Makes sense. I'll close this one too.