I’m in the middle of designing an API for a very basic flashcard application for learning purposes and I’m wondering if you all think there can be any improvements.
In the app, a Folder contains Folders and Sets. A Set contains Cards. The Homepage lists any top-level Sets and Folders that the I’ve created (but never cards). Here’s the URI schema I’ve come up with:
Does this seem ok? My goal is to keep the URIs terse/concise/simple and push any relationship metadata (parentFolderId, parentSetId, etc) into the body of the request. Thoughts?
3
It seems to me that the API would be more concise/simple if you structured your API to reflect the hierarchical structure of the data, partly because the structure would be self-documenting.
As it is, I don’t see a way for a client to e.g. get the sets within a particular folder; with more structure you could do:
GET /folders/100/sets
It really depends on what you think your clients will need to be able to do.
Also, I would probably support GET by returning a list for requests to a collection URL like /folders
, but if you don’t think it would be used for whatever reason, you’d probably want to return a status of 405 Method Not Allowed
instead of an error.
Other than that, your use of POST, PUT, and DELETE seem correct to the best of my knowledge.
Just a note: one detail that’s sometimes confusing is that PUT can also be used to create resources. The difference between that and POST is that, with PUT, your client already has the resource id and includes it in the request body; with POST you’re expecting the service to create an id for the resource. You might use that differentiation if you’re using a natural key to identify a resource, e.g. username for a user resource; in that case you would use PUT to create or update the user.
2
Mike Partridge has the right answer above, but I just wanted to add.
Here’s a good reference for the type of responses you should send to your restful requests.
Specifically, you should return 404 alongside PUT/DELETE requests to the collection (/folders) as well as for POST requests to the object (/folders/id).
Also, resources tend to be nested when it’s relevant/appropriate to do so.
It seems like in your case, folders will always be a top level element, sets will always be in a folder, and cards will always be in sets, thus:
/folders/:id/sets/:id/cards/:id
should be an allowed resource
I’ve seen this refered to as the digging-deeper-path-and-backspace convention where it’s easy to move up the tree simply by backspacing to the last /
The last link I provided has a lot of example URLs that you might use in a RESTful scheme. Another example excludes the collection names for child resources when only a specific child resource may exist at n-level:
/folder/:id/:set_id/:cards_id
I apologize if I caused more confusion. My point is there are a lot of options that are considered acceptable by different groups. Whatever convention you go with, just keep it consistent, and have good documentation for anyone who ends up using your API.