toastdriven / restless

A lightweight REST miniframework for Python.
http://restless.readthedocs.org/en/latest/
BSD 3-Clause "New" or "Revised" License
832 stars 107 forks source link

added support for custom response status #121

Closed yuriescl closed 4 years ago

yuriescl commented 4 years ago

This allows passing a custom status to an endpoint HTTP response by using a tuple:

def update(self, pk):
    try:
        Post = Post.objects.get(id=pk)
        status = 200
    except Post.DoesNotExist:
        post = Post()
        status = 201

    post.title = self.data['title']
    post.user = User.objects.get(username=self.data['author'])
    post.content = self.data['body']
    post.save()
    return post, status   # status can be passed here

Fixes #118

yuriescl commented 4 years ago

The only downside I can see using this approach is if the return type is a tuple, this would conflict with the status format. Another way of allowing a custom status would be to create a self method like is_authenticated() but sounds like too much for just the status.

sajoku commented 4 years ago

I think this functionality is already present. There are various Error classes you can raise inside the API that correspond to a HTTP status.

from restless.exceptions import UnprocessableEntity

def update(self, pk):
        extension_period = extension.get(action, None)
        if self.extend_with(extension_period):
            return {"success": True}
        else:
            raise UnprocessableEntity(self.message)

Here is the relevant doc section: https://restless.readthedocs.io/en/latest/reference/exceptions.html?highlight=exception#module-restless.exceptions

yuriescl commented 4 years ago

@sajoku Hi, thanks for the response. Yes, there are custom exceptions but this pull request allows a custom status for successful responses. For example, a PUT might return 200 or 201, see my example.

yuriescl commented 4 years ago

This approach, to return a tuple with the custom successful status, might not be the best option. There could be a custom response class like Response which if used, contains the custom status. Example:


def update(self, pk):
    try:
        Post = Post.objects.get(id=pk)
        status = 200
    except Post.DoesNotExist:
        post = Post()
        status = 201

    post.title = self.data['title']
    post.user = User.objects.get(username=self.data['author'])
    post.content = self.data['body']
    post.save()
    return Response(post, status) # if Response class is used, a custom status can be set
```'
sajoku commented 4 years ago

@sajoku Hi, thanks for the response. Yes, there are custom exceptions but this pull request allows a custom status for successful responses. For example, a PUT might return 200 or 201, see my example.

Ah yes I haven't had the need for this yet. Would it make sense to package this up in a status class though? (like the exceptions).

from restless.response_statuses import HttpCreated
def update(self, pk):
    return HttpCreated(body)

Not sure about this implementation though but I think this is more like how the exceptions are also handled.

yuriescl commented 4 years ago

@sajoku Hi, thanks for the response. Yes, there are custom exceptions but this pull request allows a custom status for successful responses. For example, a PUT might return 200 or 201, see my example.

Ah yes I haven't had the need for this yet. Would it make sense to package this up in a status class though? (like the exceptions).

from restless.response_statuses import HttpCreated
def update(self, pk):
    return HttpCreated(body)

Not sure about this implementation though but I think this is more like how the exceptions are also handled.

This is a great idea, it follows the exception handling pattern. It's preferable over the tuple I think.

yuriescl commented 4 years ago

@sajoku I'm gonna close this Pull Request and leave #118 open as a wrapper class would be a better solution.