People have been talking about including hypermedia with REST Resources, but
there are very few public examples that implement all of it. One common
technique is to add *_url
attributes:
{ "id": 1
, "self_url": "/issues/1"
, "comments_url": "/issues/1/comments"
}
This only gives you room to put a URL. Because of this, I've been leaning towards HAL:
{ "id": 1
, "_links":
{ "self": {"href": "/issues/1"}
, "comments": {"href": "/issues/1/comments"}
, "close": {"href": "/issues/1/close", "method": "post"}
}
}
Should hypermedia tell you when you have permissions to access those resources?
// admin permissions
{ "id": 1
, "_links":
{ "self": {"href": "/issues/1", "method": "get,patch,delete"}
, "close": {"href": "/issues/1/close", "method": "post"}
}
}
// read-only permissions, no access to close/update issues
{ "id": 1
, "_links":
{ "self": {"href": "/issues/1", "method": "get"}
}
}
The HAL spec doesn't mention method
properties at all. But, I think letting
a client know the difference between an Issue I can edit or close is very
useful. Is it any better if I have a separate relation for each action?
{ "id": 1
, "_links":
{ "self": {"href": "/issues/1", "method": "get"}
"edit": {"href": "/issues/1", "method": "patch" }
"delete": {"href": "/issues/1", "method": "delete" }
, "close": {"href": "/issues/1/close", "method": "post"}
}
}
Finally, is the "close" relation even appropriate? Or should I assume clients know they can close Issues by setting "state" to "closed" (which is how the GitHub Issues API works)?
I like, but I wonder if (possibly) conflating resources and state transfers might end up being a bad idea. The comments on a ticket are a related resource, but closing the ticket is an action you can take related to the current resource. For relations, discovering acceptable methods via
OPTIONS
seems totally reasonable - but an action seems like it ought to be tied to a given method.Another approach might be to model the actions as either resources or properties: You either close a resource by changing the "closed" property to true, or you go the attached
ticket_state
resource or something. Does... does any of that make sense or am I way off base?