This is in support of and expanding on these discussions:
I want to express relationships between words in a language (learning) API. Just to review our grammar:
Verb infinitive: to go
3rd person singular present: he/she/it goes
3rd person singular past: he/she/it went
If I want to express in a document the relationship between these words, it would be natural to use the relationships
field.
To wit:
{
"data":{
"id":"to go",
"type":"verb",
"relationships":{
"conjugations":{
"data":[
{
"id":"goes",
"type":"verb",
"attributes":{
"tense":"present",
"person":3,
"number":"singular"
}
},
{
"id":"went",
"type":"verb",
"attributes":{
"tense":"past",
"person":3,
"number":"singular"
}
}
]
}
}
}
}
The prototypical use case for the jsonapi 1.0 spec seems to make the assumption that any and all relationships can be (and should be) clearly stated by a single field (e.g. “father”) rather than as a set of attributes (e.g. “parent”, “adoptive”, “male”, “step”). To have universal applicability, I really think this restriction should be reconsidered. In short, a relationship often needs to be described. An ‘author’ has a clear relationship to a ‘book’, but what is the relationship of the word ‘go’ to the verb ‘to go’? The answer is ‘it depends’.
To expand, jsonapi 1.0 spec would have the word attributes in the example included in a resource object like so:
"included":[
{
id: "goes",
type: "verb",
"attributes":{
"tense":"present",
"person":3,
"number":"singular"
}
},
{
"id":"went",
"type":"verb",
"attributes":{
"tense":"past",
"person":3,
"number":"singular"
}
}
]
But how do these following attributes fit into this resource object scheme?
1st person singular present: I go
2nd person plural present: we go
"included":[
{
id: "go",
type: "verb",
"attributes":{/* what goes here?? This isn't the place for it. */}
}
For English, it may be easy (though awkward) enough to do:
"conjugations":{
"data":{
"present-1person-singular":{
"id":"go",
"type":"verb"
},
"present-2person-plural":{
"id":"go",
"type":"verb"
}
}
}
But this still forces the client to parse the key to understand the relationship of these words, and it doesn’t really work for, specifically, languages like Finnish which can have over a hundred such relationships from a single base word; nor for any of the literally infinite other phenomena in the Universe for which structured relationships cannot be captured easily using a single field (is an ‘author’ also a ‘father’?).
Or, you could do:
"included": {
"conjugations":[
{"id":"present-1person-singular",
"type":conjugation",
"attributes":{
"tense":"present",
"person":1,
"number":"singular"
}
} /// etc...
]
}
and then:
"conjugations":[
{
"id":"go",
"type":"present-1person-singular"
},
{ "id":"go",
"type":"present-2person-singular"
} /// etc...
]
But at this point, you’re struggling with the spec. It’s working against you, not for you.
I’m tempted to do this, wherein if “meta” contains an “attributes” field, it’s essentially the same as putting “attributes” into the resource identifier, but without breaking spec. A client using the API would just need to be aware. A kind of informal spec, perhaps.
Thoughts?
"conjugations":{
"data":[
{
"id":"goes",
"type":"verb",
"meta":{
"attributes":{
"mood":"indicative",
"tense":"present",
"polarity":"positive",
"person":3,
"number":"singular"
}
}
},
{
"id":"went",
"type":"verb",
"meta":{
"attributes":{
"mood":"indicative",
"tense":"past",
"polarity":"positive",
"person":3,
"number":"singular"
}
}
}
]
}