This isn’t an edge case. If you are filtering on it, it’s not metadata.
Lets consider a bit more the example I gave of a weighted graph. You don’t search the weighted graph for edges of a certain weight, because that would have no meaning outside of the context of the vertices and edge itself making it truly metadata. You might however, care if the edge relationship is a “to_node” or “from_node”, which would make it a resource as these are attributes.
If you need to interact with the relationship attributes in a way like filtering, then this is a resource and should be designed and included as one. Using some standard path conventions for clarity, you would end up with a document that looks something like this.
{
"data":{
"type":"node",
"id":"13",
"attributes":{
"node_name": "step5",
"value":"something"
},
"relationships":{
"edge":{
"links":{
"self":"http://example.org/node/13/relationships/edge",
"related":"http://example.org/edge?filter[node]=13"
},
"data":[
{"type": "edge", "id":"25"},
{"type": "edge", "id":"28"}
]
}
},
"links":[
{
"self":"http://example.org/node/13"
}
]
},
"included":[
{
"type":"edge",
"id":"25",
"attributes":{
"weight":"15"
},
"relationships":{
"from_node": { "type": "node","id":"16"},
"to_node": { "type": "node","id":"13"}
}
},
{
"type":"edge",
"id":"28",
"attributes":{
"weight":"20"
},
"relationships":{
"from_node": { "type": "node","id":"13"},
"to_node": { "type": "node","id":"17"}
}
},
{
"type":"node",
"id":"16",
"attributes":{
"node_name": "step4",
"value":"something"
},
"relationships":{
"edge":{
"links":{
"self":"http://example.org/node/16/relationships/edge",
"related":"http://example.org/edge?filter[node]=16"
}
}
},
"links":[
{
"self":"http://example.org/node/16"
}
]
},
{
"type":"node",
"id":"17",
"attributes":{
"node_name": "step6",
"value":"something"
},
"relationships":{
"edge":{
"links":{
"self":"http://example.org/node/17/relationships/edge",
"related":"http://example.org/edge?filter[node]=17"
}
}
},
"links":[
{
"self":"http://example.org/node/17"
}
]
}
]
}
Once you create this resource, the answer is simple, you use the conventions outlined in the specification for filtering, querying, inclusion, and sparse fieldsets.
If you only needed the weight as a bit of information to come along with the relationship then you can use the meta field. If you need to operate on the attributes, you are talking about a resource and this should be accounted for in the design of your API using the standard conventions of JSONAPI.
As a general rule, you should use meta if and only if it is not reasonably feasible to do what you want to do within the normally defined bounds of the specification.