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.

+3


source to share


1 answer


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.

+5


source







All Articles