Skip to content
Thomas Pollet edited this page May 11, 2020 · 3 revisions

jsonapi_rpc

While Json:Api is only concerned with CRUD operations, SAFRS does provide the jsonapi_rpc decorator that can be used to expose methods. The following decorated method from the [demo_pythonanywhere_com.py] example (https://github.com/thomaxxl/safrs/blob/master/examples/demo_pythonanywhere_com.py) demonstrates this functionality:

    @jsonapi_rpc(http_methods=["POST"])
    def send_mail(self, email):
        """
            description : Send an email
            args:
                email: test email
            parameters:
                - name : my_query_string_param
                  default : my_value
        """
        content = "Mail to {} : {}\n".format(self.name, email)
        with open("/tmp/mail.txt", "a+") as mailfile:
            mailfile.write(content)
        return {"result": "sent {}".format(content)}
curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' -d '{
   "meta": {
     "method": "send_mail",
     "args": {
       "email": "test email"
     }
   }
 }' 'http://thomaxxl.pythonanywhere.com/api/People/33ac6339-9160-4f64-9483-77a002364a03/send_mail?my_query_string_param=my_value'

will return

{
  "meta": {
    "result": {
      "result": "sent Mail to Reader 0 : test email\n"
    }
  }
}

As you can see, the result returned by the method is encapsulated in the meta part.

Format jsonapi response

By default, jsonapi_rpc results are returned in the meta part of the response. It is also possible to encapsulate the response in a json:api formatted response body by wrapping the result data in a SAFRSFormattedResponse object, for example:

    @classmethod
    @jsonapi_rpc(http_methods=["POST"])
    def my_rpc(cls, *args, **kwargs):
        """
            description : Generate and return a jsonapi-formatted response
            pageable: false
            parameters:
                - name : my_query_string_param
                  default : my_value
            args:
                email: test email
        """
        print(args, kwargs)
        result = cls
        response = None
        try:
            instances = result.query
            links, instances, count = paginate(instances)
            data = [item for item in instances]
            meta = {}
            errors = None
            response = SAFRSFormattedResponse(data, meta, links, errors, count)
        except Exception as exc:
            safrs.log.exception(exc)

        return response

Returning a response that is not jsonapi compliant

If you don't want the data returned in the meta part but want to craft your own response, you can set the jsonapi_rpc valid_jsonapi argument to False:

@jsonapi_rpc(http_methods=["POST"], valid_jsonapi=False)