+++ title = "json-ld makes it easy to do bad json" summary = "the real problem is not the ld, it's that it allows you to keep doing bad json. the context mapping is a wonderful tool for indirection, which is good when you want to take ambiguous structure and make it unambiguous [...] but if you're working at the plain-json level then you are at the mercy of whoever designed the json api/structure/schema in the first place. you have to deal with all the ambiguity inherent to the bad json [...] to be consistent with the *compacted* form means that you have to be as indirect as the context mapping tells you to be" date = 2024-10-13T13:20:00-05:00 source = "https://mastodon.social/@trwnh/113301496365344814" +++ thinkin bout the jsonld hate again and i think the real problem is not the ld, it's that it allows you to keep doing bad json. the context mapping is a wonderful tool for indirection, which is good when you want to take ambiguous structure and make it unambiguous (through expansion), but if you're working at the plain-json level then you are at the mercy of whoever designed the json api/structure/schema in the first place. you have to deal with all the ambiguity inherent to the bad json. in a sense, the as2 requirement to be consistent with the *compacted* form means that you have to be as indirect as the context mapping tells you to be. if the w3.org/ns/activitystreams context did some wack shit then you would have to unwrap all the resulting wack behavior. and type:id is the biggest kludge ever because it makes it ambiguous whether anything is a literal value or an actual object. here's an example from an earlier post > compare this > > ``` > { > "to": [{"id": "some-actor"}] > } > ``` > > with this > > ``` > { > "to": "some-actor" > } > ``` > > yes the second one looks cleaner but it actually is very messy when you try to do anything with it > > if you were required to do the first one, then implementations would have a LOT less to worry about {cite="https://mastodon.social/@trwnh/113266766055627285" card="mastodon.social/@trwnh"} simply *dropping* type:id from the context mapping of every single term would have changed the compacted output to use a json hashmap every time you refer to an object, and each object can have a single key `id` in it at minimum. i bet if this was the case, then the complaints about "jsonld" would *sharply* drop. it would just be a fancy namespace at that point, and people don't complain about aliasing/includes/imports as much. this is something that can't be fixed about as2 as a profile or media format unless you make a new context document and force people to be consistent with that new context mapping, which would have to limit itself to simple term definitions. (none of the fancy stuff.) the thing is, humans can deal with ambiguity. machines can't. as2 is overly optimized for human readability, to the point that it creates a lot of ambiguity for machines. the proper use of context mappings is to transform ambiguous json into unambiguous json(ld). not to force everyone to use ambiguous json in exactly the same way that you use it. this is also made worse by the fact that the as2 vocab is sometimes defined in a way that is so "bad" that it is *impossible* to express using a single term! case in point: take as:closed. it can be both an object (Object or Link), or a literal (datetime or boolean). how do you model that cleanly? if you were doing this "right", then you would end up needing a second term `closedBy` to represent cases where as:closed refers to an object, instead of `closed` which has a literal value. a similar thing happens with as:items. we actually need two terms: `items` which refers to the default container of an unordered set, and `orderedItems` which tacks on container:list to the context mapping's term definition. this is not the fault of jsonld, it's the fault of overly broad schemas/"bad json". a little more explicitness upfront would have saved everyone a lot of trouble, and it's sad that as2 got finalized in the state that it did. the vocabulary is generally decent in the concepts and building blocks it identifies, but they just don't connect in the way that you'd expect or even understand. --- > [...] i made a shitpost that as2 should have used hal+json instead https://mastodon.social/@trwnh/113266744971942546 honestly we don't need to use hal+json specifically but we should definitely take inspiration from it in what we want our compacted jsonld to look like. [...] you could simplify a lot of this with jsonld as well, for example eliding out the set/list stuff. but the more "context" you add/require, the harder it is to undo that. i'm pretty sure that when people say they hate jsonld what they mean is that they hate that this inherent complexity is hidden from you by the context mapping there's probably a midway point or compromise [...] the problem is that AS2 is just weird in so many ways due to that underspecification and also what i refer to as the connections between building blocks -- things like the Invite activity being a special case where the as:object is not the actual object of that activity, you're not inviting a party, you're inviting *someone* to that party. that's just bad semantics at the modeling level. [...] all json really needs is a way to signal that something is an object and not a literal. we have a way of doing that: make the object into a json object! this means actor:someone is not enough anymore, you need actor:{id:someone} similarly the way you signal that something can have multiple values is not to just say "everything can have multiple values", it's to make it an array. but then you need to specify whether the array is ordered or unordered. which you can do with objects so instead of {"items": "something"} you would need to be explicit and say {"items": { "list": [{"id": "something"}] }} this differs very slightly from json-ld expanded form in that a) you can use simple term definitions in an optional context mapping to provide simple namespacing lookup, and b) your entrypoint is not always an implicit graph, it's allowed to be an object, and if you want to refer to a graph then you can use a graph object instead