Implementing RPC in RESTful API Using DRF
I am using Django Rest Framework to represent RESTful API. I have a router / viewet / serializer creating an endpoint for a resource Person
:
/api/People/<id>/
I would like some way to trigger a non-idempotent action on this resource (for example send-email-to
). One idea I had to do without redoing a lot of the routing / serialization infrastructure was to add a write-only boolean field to the serializer:
class PersonSerializer(serializers.ModelSerializer):
send_email = serializers.BooleanField(write_only=True, required=False)
and then add a write-only property to the model:
class Person(models.Model):
...
def do_send_email(self, value):
# We also need to check the object is fully constructed here, I think
if do_send_email:
...
send_email = property(fset=do_send_email)
and then I can PATCH
up to the endpoint with the payload send_email=True
.
Is this the best way to execute RPC function using REST API? Is this the best way to achieve this in DRF? Ideally, I would like to solve this problem by requiring as little as possible (i.e. seeing how few lines of code is a solution). send-email-to
is not the only action that I would like to handle.
source to share
You can use additional actions that drf provides. In your case especially, I would use @detail_route.
Something like that:
@detail_route(methods=['post'])
def send_mail(self, request, pk=None):
send_mail_to(pk) # Write here your email function.
You must define this function in the Person view, so to call this function, you need to POST to / people / {person_id} / send_mail where {person_id} is the person's primary key.
As a side note, since this function is being called synchronously from the client and it might take a while, I would recommend you use celery . This will allow you to call send_mail_to function asynchronously without delaying the user's response.
source to share