call remote method (action) over DRF

118 views
Skip to first unread message

Jan Krňávek

unread,
Feb 5, 2019, 4:56:18 AM2/5/19
to Django REST framework
Hello everybody,
i need to  call remote method and i want to pass in parameters and  to get response, all  in json format.

Suppose i  have an endpoint  /api/actions  and will POST  {"action":"do_some_cals", "param1":"111","param2":"222"}
and will get reponse { "result":"333"}

There will be no model for any methods

How can i do this in  DRF , is there better way, how to design calling methods in DRF?

Thank you in advance for help.
Hanz

Alan Crosswell

unread,
Feb 5, 2019, 7:54:30 AM2/5/19
to django-res...@googlegroups.com
SOAP-style remote method invocation is not RESTful. In REST, resources are nouns and the only verbs are the HTTP methods — GET, POST, PUT, PATCH, DELETE, etc. you’ll want to trigger actions in your views or models based on values of the resources. See 


--
You received this message because you are subscribed to the Google Groups "Django REST framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-rest-fram...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
--
Alan Crosswell
Associate VP & CTO

Alan Crosswell

unread,
Feb 5, 2019, 8:28:57 AM2/5/19
to django-res...@googlegroups.com
Some (less opinionated than me) people might refer you here: 

But bear in mind that DRFs Model-based serializers implement CRUD via POST, GET, PUT/PATCH, and DELETE). JSONAPI.org is a good strict REST design. See the Django-restframework-jsonapi package. 


Sanjay Bhangar

unread,
Feb 5, 2019, 8:29:21 AM2/5/19
to django-res...@googlegroups.com
On Tue, Feb 5, 2019 at 6:24 PM Alan Crosswell <al...@columbia.edu> wrote:
SOAP-style remote method invocation is not RESTful. In REST, resources are nouns and the only verbs are the HTTP methods — GET, POST, PUT, PATCH, DELETE, etc. you’ll want to trigger actions in your views or models based on values of the resources. See 



Sorry to digress a bit here, but I would disagree that remote method invocations as described here is "SOAP-style". It is not "RESTful", but by no means does it need to be anything like SOAP ( https://en.wikipedia.org/wiki/SOAP ).

I think the technical term for this kind of style of "method invocation" over an API would be similar to "RPC" - or Remote-Procedure-Calls, something like https://en.wikipedia.org/wiki/JSON-RPC

I think debating the pros and cons of these styles can be endless :-) - personally, I like to stick to RESTful patterns wherever possible, but for the case described here where the user just wants to pass in some parameters and get a response, and this is not tied to a data model per se, I also  think forcing a RESTful approach on something that you really want to think about as "I want to pass in two parameters to a URL and get a response" often adds complexity.

In this case, Hanz, personally my advice would be to start with a very simple implementation of this so you understand how the parts work, and then add framework as needed.

IMHO, the "simplest" implementation would be to just use plain django, have an entry in your urls.py that points to a view function. In your view function, you simply read your GET or POST parameters from the request, perform your computations in python code, and return some JSON as response (you can use a JsonResponse object: https://docs.djangoproject.com/en/1.11/ref/request-response/#jsonresponse-objects ) .

When doing something similar with Django Rest Framework, I have used the api_view decorator: https://www.django-rest-framework.org/api-guide/views/#api_view - this lets one write simple functions mapped to URLs, and  reduces boilerplate you may have across these different view functions. Hopefully the examples there make sense to get you started.

Hope that helps,
Sanjay

Jan Krňávek

unread,
Feb 5, 2019, 9:17:28 AM2/5/19
to Django REST framework
Alan, Sanday for your reply I appreciate it...
First at all , I know a design of REST , i successfully run several endpoints in a production. (i usually use great viewsets with mixins, model serializer and the other common DRF stuff...)
At the moment i have to solve  remote method call and i dont want to do some extra infrastucture. I think that it will be solvable through  DRF although  it wont be strict restfull.
i have same solution in my mind and later i will post it here .
Hanz

Dne úterý 5. února 2019 14:29:21 UTC+1 Sanjay Bhangar napsal(a):

Jan Krňávek

unread,
Feb 8, 2019, 2:40:03 AM2/8/19
to Django REST framework
If anybody cares, here is my solution. I POST {'action':'calc','args':{'arg1':1,'arg2':2}} into endpoint /api/customers/action   for an execution. An advantage for me is that i can use robust DRF infrastructure.

Any ideas for improvement are welcome.
Hanz

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)

   
def calc(self, args):
        arg1
= args["arg1"]
        arg2
= args["arg2"]
       
return arg1 * arg2


Dne úterý 5. února 2019 15:17:28 UTC+1 Jan Krňávek napsal(a):

Sanjay Bhangar

unread,
Feb 8, 2019, 2:46:31 AM2/8/19
to django-res...@googlegroups.com
On Fri, Feb 8, 2019 at 1:10 PM Jan Krňávek <hanz.k...@gmail.com> wrote:
If anybody cares, here is my solution. I POST {'action':'calc','args':{'arg1':1,'arg2':2}} into endpoint /api/customers/action   for an execution. An advantage for me is that i can use robust DRF infrastructure.

Any ideas for improvement are welcome.

This looks really clean / solid to me and definitely an improvement over a more naive function-based approach I had mentioned.

Thanks for posting what you came up with!

- Sanjay

Reply all
Reply to author
Forward
0 new messages