0

Making an API responsible for storing files.

The File data model looks something like this

public class File
{
    public Guid Id { get; set; }
    public string Path { get; set; }
    public string Contents { get; set; }
}

So with the post request I setup in my controller (to create the file), I need the id of the file, the path the file will be stored (relative to a root path I have pre-configured), and the contents of the file.

I'm wondering if it's better practice to require a File data model to be passed in the body of the request, or to have the id and path both as query parameters and the contents in the body of the request.

Jacob
  • 439
  • 6
  • 19
  • What's the desired behaviour with 2 identical calls, one after the other? E.g store 2 files, overwrite existing, error... – sellotape Dec 03 '18 at 22:58
  • @sellotape The behavior would be to simply overwrite the existing file. Knowing that, do you think using the data model in the request body, or do you think the combination of query parameters and file contents in the request body is the better option? – Jacob Dec 04 '18 at 00:18

1 Answers1

0

TL;DR - use PUT /files/{id} with the content in the body.

What this depends on is - what is the (unique to your system) identity of a File? I'll assume here that it's the Id passed in by the client, and that Path is simply metadata. If path forms part of the identity as well, you'll need to adjust this accordingly.

As it's the client that supplies and determines the identity, you should probably prefer a PUT to a POST, and supply the identity in the path; e.g. PUT /files/{id} with the path and content in the body. A subsequent identical PUT leaves the system in the identical state, so it satisfies the requirement that a PUT is idempotent to observers. A subsequent non-identical PUT updates the existing content.

The HTTP spec allows some flexibility here, so you can use a POST. The latest has changed the definition of POST a little (to have broader application), but in the original (emphasis mine)...

The POST method is used to request that the origin server accept the entity enclosed in the request as a new subordinate of the resource identified by the Request-URI in the Request-Line.

... it was clearer that POST /files makes sense to create e.g. a file in a directory (their example), but POST /files/{id} makes less sense.

This discussion has some more on PUT vs POST. It's also asserted there that:

Note that the following is an error:

POST /questions/<new_question> HTTP/1.1
Host: www.example.com/

If the URL is not yet created, you should not be using POST to create it while specifying the name. This should result in a 'resource not found' error because <new_question> does not exist yet. You should PUT the <new_question> resource on the server first.

Community
  • 1
  • 1
sellotape
  • 8,034
  • 2
  • 26
  • 30