Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implementing RPC in RESTful API using DRF

I am using the Django Rest Framework to present a RESTful API. I have a router/viewset/serializer creating an endpoint for a Person resource:

/api/People/<id>/

I would would like some way of triggering a non-idempotent action on this resource (for example send-email-to). One idea I had to do so without having to re-do 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 to the end point with the payload of send_email=True.

Is this the best way to accomplish an RPC like function using a REST API? Is this the best way to accomplish this in DRF? Ideally I would like to solve this problem having to-implement as little as possible (ie see how few lines of code the solution is). send-email-to is not the only action that I would like to handle.

like image 821
Alex Rothberg Avatar asked Oct 19 '25 01:10

Alex Rothberg


1 Answers

You can use the extra actions drf provides. In your case especifically, 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 have to define this function within the Person viewset so, in order to call this function, you will have to POST at /people/{person_id}/send_mail where {person_id} is the primary key for the person.

As a side note, since this function are synchronously called from the client and it may take a while to answer, I would recommend you the use of celery. This will allow you to call the send_mail_to function asynchronously without delaying the user response.

like image 119
argaen Avatar answered Oct 21 '25 15:10

argaen



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!