0

For fetching data it is recommended to usually use a GET and for submitting a form, a POST. How about for the following function, which 'checks out' an item:

@validate_credentials
@csrf_exempt
@acceptable_methods(???)
def cue_checkout(request, cue_id, user=None, checkout=True):

    cue = Cue.objects.filter(pk=cue_id, user=user)
    if not cue.exists():
        return HttpResponseForbidden('Invalid Cue supplied.')

    cue = cue[0]
    CueAssignment.objects.create(cue=cue, user=user, checkout_timestamp=timezone.now())
    return HttpResponse()

I'm thinking since we're modifying data it should be a POST, but could someone please explain what the correct method would be here and why?

David542
  • 104,438
  • 178
  • 489
  • 842
  • possible duplicate of [When do you use POST and when do you use GET?](http://stackoverflow.com/questions/46585/when-do-you-use-post-and-when-do-you-use-get) – Robby Cornelissen Nov 06 '14 at 07:02

2 Answers2

2

The W3 specifies two terms used to describe HTTP methods.

The first is "Safe" meaning that it does not mutate data resources on the server.

The second is "Idempotent", meaning the results of the request should be the same as long as the state of the data resource has not changed (independent of the idempotent request).

Because you are creating objects on the server, you should be using POST, as GET is defined as a safe and idempotent action. POST meanwhile is neither safe nor idempotent (since we may reject the creation of the object due to constraints). Moreover, you should be enforcing csrf_protection to avoid the re-use of session cookies maintaining the user's permissions to be freely used to create objects.

There's a nice, quick table here use as a quick reference for common methods.

DivinusVox
  • 1,133
  • 2
  • 12
  • 27
1

You can think of checking out an item as updating some resource e.g. a cart. Thus, in this case, POST or PUT make the most sense.

POST is used to modify a resource or create a resource. Use POST to create a resource when the resource's identifier is not yet known e.g. on creation, the server will determine the resource's id.

Modify: POST /my/resource/[existing-id] - modify a resource at a known location

Create: POST /my/resource - With this operation, you might return a 201 with a Location header identifying the new resource

PUT is used to create a resource or overwrite it. In both cases, the resource id is known and fully qualified.

Create: PUT /my/resource/[id] - create a resource at a known location

Modify: PUT /my/resource/[existing-id] - update a resource at a known location

Differences:

PUT is idempotent. Invoking it multiple times always results in the same result

POST is not idempotent. Invoking it multiple times may result in multiple new resources.

cmd
  • 11,622
  • 7
  • 51
  • 61