Hi everyone,
I want to show my solution how to add support for remote calling procedure (method) into an existing RESTful API infrastructure.
I extend APIView and override POST method that is a key part of code. I called the new class surprisingly RunActionView.
# The APIView for calling custom methods from jsonschema import validate from rest_framework import status from rest_framework.permissions import IsAuthenticated from rest_framework.views import APIView from rest_framework.response import Response class RunActionView(APIView): permission_classes = (IsAuthenticated,) def post(self, request): data = request.data action = data.get("action", '') args = data.get("args", '') r_data = {} if action: try: r_data["result"] = getattr(self, action)(args) r_data["success"] = True except Exception as e: r_data["message"] = f"Action {action} failed.\n{e}" r_data["success"] = False else: r_data["message"] = f"No action set." r_data["success"] = False return Response(r_data, status=status.HTTP_200_OK) # the custom method def calc(self, args): schema = { "type": "object", "properties": { "arg1": {"type": "number"}, "arg2": {"type": "number"}, } } validate(args, schema) arg1 = args["arg1"] arg2 = args["arg2"] result = arg1 * arg2 return result
Make sure to add our class RunActionView into file urls.py.
# the content of urls.py urlpatterns += path('api/actions/', RunActionView.as_view()),
There is an example of calling the remote method “calc” with two parameters arg1 and arg2.
# the rest client example with the token authentication url = 'https://127.0.0.1/api/tasks/' # add your a super secret token here token = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' head = {'Authorization': f'Token {token}'} data = { "action": "calc", "args": {"arg1": 11, "arg2": 22}, } response = requests.post(url, headers=head, json=data) payload = response.json() if not response.ok: raise Exception(f'POST {url} code:{r.status_code}\n{payload}') else: print(payload)
I know that this approach is not perfect and that is not strict RESTfull and deserves some improvements.
My example can be useful as a basic scaffold for your final solutions.
That is all and as always, any improvement ideas are welcomed.
Enjoy!
Hanz