2

I am designing a REST api for a document management system. To make the API more natural, I thought about using the natural identifier for a file, which is it's path (usually having forward slashes "/" in it), and not something like an artificial id such as a UUID.

Naturally, a user would identify a file by it's path:

/path/to/file.txt

Unfortunately, this clashes with common, good API design.

This would work:

Retrieving a file: GET /api/v1/files/<path/to/file.txt>

However, other methods you would like to have, will become a bit problematic:

Retrieving a file list of a folder: GET /api/v1/folders/<path/to/folder>/files

My thoughts so far:

  • avoid unique identifiers with "/" in it entirely, and use an artificial UUID (such as Alfresco is using NodeId / NodeRefs). This would add another layer of abstraction to it, where a unique id is just not very natural from a business domain perspective
  • don't use the identifier in the url path but in a parameter (against good API design patterns)
  • (requesting the API users to replace the / with another character is of course also not an option)

Of course, files and folders as we know it from a file system, are naturally identified by it's path. In that particular case, one could argue that if someone wants to use the path as the identifier, than the correct way for doing:

Retrieving a file: GET /api/v1/files/<path/to/file.txt>

would actually be:

Retrieving a file: GET /api/v1/folders/<path>/folders/<to>/files/<file.txt>

if we want to be really correct here.

Update: I want to ask the community about best practices and experiences here - especially when Dropbox and Google Drive both use two different approaches (see first answer and comments below): DropBox is using the path while Google Drive is using IDs.

6

You may wish to look into Google Drive API's way of handling this. In their case, paths are abstractions and files are selected by id.

A file is a resource. It can belong to a folder, so it has a 'Parents' property. It can belong to multiple folders (either as a shared item, or to simulate soft-links), so it can have multiple 'Parents'. It can be moved to a different "folder", in which case the actual resource does not change location -- its parents property is just changed. The filename is not used in the URI, because an id is unique and a string can have odd characters.

  • Thanks for the link to Google Drive API. Yes, it's the same concept that Alfresco is also using with the NodeRef/NodeId. The renaming case is a good point, which makes sense. – Mathias Conradt Jul 24 '15 at 17:09
  • Interestingly, the Dropbox API uses the path as well (as in my OP) as url path variables. dropbox.com/developers/core/docs#files-GET – Mathias Conradt Jul 24 '15 at 20:57
  • Using file paths directly seems like the biggest soon-to-be-headache imaginable. Any time a user wants to change a file location you have to change the literal file location? Recipe for disaster. Unique ids are better, because a file is an object, and objects have properties such as parent and children[]. Why bother with file paths at all in your API? Ids are easy (especially for your API consumers to keep track of!). – Chris Cirefice Jul 25 '15 at 6:22
2

Forget about files for a moment.

You have an API, and at some point you need to insert identifiers specific to your application. Since your application isn't primarily interested in the features of the API, and because these identifiers are determined without even knowing about the API, you need to be able to translate an arbitrary identifier into something that the API can handle.

There is a standard mechanism for this, which is percent encoding. It handles all these pesky cases like identifiers containing slashes, less than and greater. For example, on my Mac, /"what</do">you think/"about>>this is a perfectly valid path with the three path components "what<, do">you think, and "about>>this. Percent encoding has no problem with this.

1

First of this

/api/v1/someresource

is not actually good REST api design. The version of the api should not be in the path of a resource. A resource is just a resource. The version of the data structure representing the resource should be in the MIME time. For example when you go to a webpage you don't have URLs like this

www.newyorktimes.com/html5/headlines
www.newyorktimes.com/html2.1/headlines

you just have this

www.newyorktimes.com/headlines

And the browser figures out if it can display HTML5 or HTML2 or XML or what ever the search reports it can return for that resource. The version of HTML used is in the meta information for the representation of the resource headlines.

So don't do that with your API either. If there is a version 1 of a resource and a version 2 of that resource record that in the mime time of the resource. If you are expecting the client to know the location of resources based on the version of the API you are also not following REST. You should be able to move a resource to another location without having to up the API version.

There is nothing wrong then with the URI

www.myserver.com/files/path/to/file.txt

or even just

www.myserver.com/path/to/file.txt

if that makes sense with regard to how you want to structure your resources. This is how static files are served on a web server and it has worked fine for decades.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.