(Pardon the question title; hard to summarize this question.)
On Facebook, you like things. On Twitter, you follow people. On GitHub, you also follow people and star repos and gists.
All of these cases are pretty similar: those connections are lightweight, not really "resources" themselves. E.g. none of those three APIs expose public IDs for such connections.
This raises the question: what's the "best" (in terms of REST) way to expose an API for creating/querying/deleting those connections?
Facebook does [1]:
GET /:id/likesto query an object's likes (more precisely, the users that like that object)POST /:id/likesto like something (on behalf of the auth'ed user; no req body needed)DELETE /:id/likesto unlike something (on behalf of the auth'ed user)
The querying and creating make sense, but the DELETE is a bit "unRESTful", because you're not actually deleting the /:id/likes resource (an array of users that like that object).
This discrepancy shows itself in another case [2]:
GET /me/likes/:idto query whether you like something
So querying your connection is querying a totally different resource than creating or deleting it.
GitHub leans to the /me/likes/:id style for following users and starring repos [3]:
(Note that GitHub's /user represents the auth'ed user, like Facebook's /me.)
GET /user/starred/:owner/:repofor querying whether you have a repo starred (returns 204 or 404, no body either way)PUT /user/starred/:owner/:repofor starring a repo (no body needed in request)DELETE /user/starred/:owner/:repofor unstarring a repo
This is much more consistent, but unfortunately this separates individual "stars" from the group:
GET /repos/:owner/:repo/stargazersto query the users who've starred a repo
GitHub, interestingly, uses a different style for starring gists [4]:
GET /gists/:id/starfor querying whether you have a gist starredPUT /gists/:id/starfor starring a gistDELETE /gists/:id/starfor unstarring a gist
This keeps the starring action with the gist resource, like Facebook, rather than the user resource.
GitHub doesn't publicly expose gists' stargazers, but presumably it'd be e.g.:
GET /gists/:id/stargazersto query the users who've starred a gist
While "stargazers" is indeed a different resource/name than "star", the names are similar and clearly related, and they're both on the same resource.
The only downside I can think of to this is naming the resource. Something like star works, but actions like follow or like are trickier.
(Not bothering to include the Twitter API as an example since it's hardly RESTful.)
There's clearly no perfectly RESTful API for creating/querying/deleting things that aren't proper resources, but are there other pros/cons I'm not seeing, or other styles to consider?
Thanks!