Building a Remote Procedural Call (RPC) endpoint with the Django Rest Framework
The Django Rest Framework (DRF), has a lot of built in functionality that supports CRUD operations, but building an RPC endpoint requires hand-rolling much of that. Ultimately, if we’re adding an RPC endpoint to an existing API with mostly REST endpoints, we want to match the design of our new endpoint to match that of the DRF, so we need to understand what each piece does.
All of these pieces are explained in the DRF docs, but seeing a complete example and how they all work together can add clarity.
I’m going to use the example here of fulfilling a purchase. In this example, I do have a
Purchase database object that will be modified in the process. However, because other things happen too — the user is emailed a receipt, other database objects are created or modified (a course registration is created, for example), etc., this deviates from a typical REST endpoint.
Overview & Docs
So before we jump in, here’s the spoiler of what’s going to happen, and links to the relevant docs:
- We’ve got some routes, which create the urls, and point to a class based view that has several methods on it, each corresponding to an endpoint
- The view has a custom mixin, which mimics DRF’s built-in mixins
- One of these endpoints is a custom detail route, which will call
superand hit the mixin
- The mixin will do some stuff to validate & prepare the data, and call the serializer, and send a response
- The serializer will do the main logic, and prepare the data for the mixin to respond with
Let’s look at each of these in more detail.
First, we need to register the urls that our users can call. My
urls.py file looks like this:
from rest_framework.routers import SimpleRouter
from api.v1.purchases.views import Purchaserouter = SimpleRouter(trailing_slash=False)
router.register(r’’, Purchase, base_name=’purchase’)
urlpatterns = router.urls
In this case, the
Purchase that I’m registering as the view to call, is referring to a class based view, which is defined and described in more detailed below, and is different from the