RESTful API design: best way for easy CRUD connections?

(Sorry, the title of the question is difficult to summarize this question.)

On Facebook, you like things. On Twitter, you follow people. On GitHub, you also follow people and star repositories and gists.

All of these cases are quite similar: these connections are lightweight, not "resources" themselves. For instance. none of these three APIs provides public identifiers for such connections.

The question arises: what is the "best" (from the point of view of REST) โ€‹โ€‹way to open the API to create / request / delete these connections?


Facebook does [ 1 ]:

  • GET /:id/likes to request a liked object (more precisely, users who like this object)

  • POST /:id/likes to like something (on behalf of an authorized user, a body was not required)

  • DELETE /:id/likes , unlike anything (on behalf of the user to whom auth'ed was granted)

The query and creation make sense, but DELETE bit "unRESTful" because you are not actually deleting the /:id/likes resource (an array of users who like this object).

This discrepancy manifests itself in another case [ 2 ]:

  • GET /me/likes/:id to ask if you like something.

Thus, a connection request requests a completely different resource than creating or deleting it.


GitHub relies on the /me/likes/:id style for the following users and main repositories [ 3 ]:

(Note that GitHub /user represents an auth'ed user, such as Facebook /me .)

  • GET /user/starred/:owner/:repo to query if a repo is taking place (returns 204 or 404, no body anyway)

  • PUT /user/starred/:owner/:repo for the main role of the repo (the body does not need in the request)

  • DELETE /user/starred/:owner/:repo to disorder the repo

This is much more consistent, but unfortunately it separates the individual "stars" from the group:

  • GET /repos/:owner/:repo/stargazers to request users who prevented the repo

GitHub , interestingly, uses a different style for the main roles [ 4 ]:

  • GET /gists/:id/star to ask if you have a gist marked

  • PUT /gists/:id/star for the main role

  • DELETE /gists/:id/star to unorder gist

This saves the action in the lead role using a gist resource, such as Facebook, rather than a user resource.

GitHub does not publish giant writers, but presumably it will be, for example:

  • GET /gists/:id/stargazers to request users who flagged gist

While star-shaped ones do represent a different resource / name than a star, the names are similar and clearly related, and both are on the same resource.

The only drawback I can think of is to name the resource. Something like star works, but actions like follow or like harder.


(You do not need to include the Twitter API as an example, as it is hardly RESTful.)

Obviously, there is no absolutely RESTful API for creating / requesting / deleting things that are not proper resources, but are there any other pros / cons that I don't see, or other styles to consider?

Thanks!

+4
source share
2 answers

One thing that I liked in the style of /me/likes/:id is that such people feel like individual, addressable resources - for example. they have individual identifiers (this is similar to what I like).

The GitHub repo API uses this to create / query / delete star connections to repositories, but there is a discrepancy in getting all star connections for a specific repo.

Perhaps the discrepancy can be eliminated by changing the way these connections are accessed: instead of relying solely on the identifier of the object, also use the user identifier (auth'ed). For instance:.

  • GET /:owner/:repo/stargazers to request all users who interfere with this repo

  • GET /:owner/:repo/stargazers/:id to ask if user :id repo name - it could be auth'ed by specifying me !

  • PUT /:owner/:repo/stargazers/me to start the repo - this will only work for a user with auth'ed privileges

  • DELETE /:owner/:repo/stargazers/me to cancel a duplicate

Now all resources / actions are combined, actions are consistent, and naming is simple.

Edit: Another advantage of this approach is that you can easily and efficiently query if other users like the / follow / star object.

Edit: But the drawback is that the resources are not technically correct anymore - GET .../stargazers returns a list of users, but GET .../stargazers/:id returns a connection, not a user. Oh good?

[Edited again to support passing me like :id here too.]

+1
source

I think,

DELETE /: id / likes to distinguish something (from the username auth'ed)

it makes sense, since this will have a composite identifier key for the favorite object and user identifier, so specifying the identifier is simply redundant when your authenticated login already tells you who you are, and you donโ€™t even have permission to delete it anyway.

An explicit indication of this (as Aceim Kishore suggested), for example

DELETE /: id / likes / me

... maybe a little clearer.

0
source

All Articles