ActivityStreamsOrderedProperty isn't array with only one item
Sigafoos opened this issue · 1 comments
Please Describe The Problematic Behavior
I have this code:
followers := streams.NewActivityStreamsOrderedCollection()
id := streams.NewJSONLDIdProperty()
id.SetIRI(u.FollowersIRI())
items := streams.NewActivityStreamsOrderedItemsProperty()
for _, follower := range u.Followers {
log.Println("appending follower", follower.ID)
iri, err := url.Parse(follower.ID)
if err != nil {
log.Println("error parsing url for followers list:", err.Error())
continue
}
items.PrependIRI(iri)
}
followers.SetActivityStreamsOrderedItems(items)
When I hit the followers endpoint of my app, this is the response
{
"@context": "https://www.w3.org/ns/activitystreams",
"orderedItems": "http://localhost:8080/user/test",
"type": "OrderedCollection"
}
I added two calls to PrependIRI()
and the response was an array:
{
"@context": "https://www.w3.org/ns/activitystreams",
"orderedItems": [
"http://localhost:8080/user/test",
"http://localhost:8080/user/test"
],
"type": "OrderedCollection"
}
Please Describe The Expected Behavior
When there is only one item in the ordered items it still renders as an array.
Please Describe The Expected Behavior
When there is only one item in the ordered items it still renders as an array.
Ah, man. So the root issue is that one element is a "string"
and more than one is an ["array", "of", "strings"]
?
Unfortunately, these are all valid from ActivityStreams' perspective.
Fixing this is not easy. The reason this is not a straightforward fix is because these expectations are quite arbitrary. For example, this is behavior enshrined in the code-generation for non-functional properties, that funny jargon for "properties able to have >1 value".
Any change in that code-generation means it affects all such properties. So things like orderedItems
and items
make sense to have this change. When there's one item
, most will be able to handle "item": ["foo"]
. But, other non-functional properties' conventions are not this. Unfortunately, the big elephant in the room is the all-important type
property as it is also non-functional, and maybe in more than one meaning. This means such a change would cause a "type": "Create"
to be serialized as a "type": ["Create"]
, and I am willing to bet that would cause numerous insidious federation issues.
So we are caught in a valley where go-fed's rigor means the two quick & easy options are both sub-optimal. Go-fed is in a bit too deep of its own rigor to break away and live the lackadaiscal life.
So what are the options?
- Do nothing. No fun for anyone. :(
- Make the change. Pray go-fed clients' federation doesn't break peers' software.
- If the client is written in Go, change the consuming (client) side to also use the
streams
vocabulary to be able to handle this properly. Or be a Javascript client :P or other dynamically typed language (joking). The downside is it is more work for all clients involved. - Do a "real fix"
A real "fix" for this could involve:
- Finding an RDF schema definition that can properly capture this sort of expectation
- Identify, debate, and tag the non-functional properties in the vocabularies in the OWL definitions where this behavior is expected to occur
- Modify
astool
's parser to look for this OWL tag - Modify
astool
's code generator to use the tag to generate an alternative serialization method that always outputs a single element as an["array"]
- Regenerate the vocabularies