58

I want to create a REST API for a file upload service that allows a user to:

  1. Open a session
  2. Upload a bunch of files
  3. Close the session

And then later, come back and do things with the files they uploaded in a previous session.

To facilitate dealing with data about each file and dealing with the content of the file itself, this is the URI scheme I am thinking of using:

/sessions/
/sessions/3
/sessions/3/files
/sessions/3/files/5
/sessions/3/file/5/content
/sessions/3/file/5/metadata

This will allow the file metadata to be dealt with separately from the file content. In this case, only a GET is allowed on the file content and file metadata, and to update either one, a new file has to be PUT.

Does this make sense? If not, why and how could it be better?

thealchemist
  • 421
  • 4
  • 12
cdeszaq
  • 30,869
  • 25
  • 117
  • 173
  • 2
    There are many popular public REST APIs you can look at for inspiration on how to handle file upload. I'm personally more familiar with the Google Drive API https://developers.google.com/drive/v2/reference/files/insert or the (newer) Dropbox API https://www.dropbox.com/developers/reference/api There are many others... – Ferenc Mihaly Dec 08 '11 at 20:49
  • Dropbox: body is the file, metadata on URL `?` parameters. – Ciro Santilli OurBigBook.com May 07 '14 at 20:17
  • the way dropbox does it is stupid, why put the HTTP verb in the Uri. It's specified in the Http header. That's redundant and just stupid – PositiveGuy Sep 05 '14 at 15:50
  • 2
    It's to ensure support for old clients. Some clients can just do POST and GET. I like your bio though: > "[...] Who are willing to apprentice and share and learn from others....in a polite patient manor." – Erem Sep 03 '15 at 22:21

1 Answers1

15

Why do you need sessions? Is it for Authentication and Authorization reasons? If so I would use http basic with SSL or digest. As such there is no start or end session, because http is stateless and security headers are sent on each request.

Suggestion of upload resource would be to directly map as private filesystem


# returns all files and subdirs of root dir
GET /{userId}/files
GET /{userId}/files/file1
GET /{userId}/files/dir1
# create or update file
PUT /{userId}/files/file2



When uploading file content you then would use multipart content type.

Revised answer after comment

I would design your wanted separation of file-content and payload by introducing link (to file-content) inside upload payload. It eases resource structure.

Representation 'upload' resource:


{
  "upload-content" : "http://storage.org/2a34cafa" ,
  "metadata" : "{ .... }" 
}

Resource actions:


# upload file resource
POST /files
-> HTTP 201 CREATED 
-> target location is shown by HTTP header 'Location: /files/2a34cafa

# /uploads as naming feels a bit more natural as /files
POST /sessions/{sessionId}/uploads
-> HTTP 201 CREATED
-> HTTP header: 'Location: /sessions/{sessionId}/uploads/1
-> also returning payload

# Updating upload (like metadata)
/PUT/sessions/{sessionId}/uploads/1 


manuel aldana
  • 15,650
  • 9
  • 43
  • 50
  • Sessions have _nothing_ to do with authentication. They are only used to group a batch of uploads together. There is no "user" in the classic sense, other than information entered for each session. There also is no concept of a directory (currently), but there is a large amount of metadata associated with each uploaded file. – cdeszaq Dec 10 '11 at 23:53
  • ah, misunderstanding... Have a look at my updated answer (last section). – manuel aldana Dec 11 '11 at 12:13