How do I expose an inbuilt API endpoint to custom endpoints?

I need to refactor the existing inbuilt API endpoints like https://abc.com/api/method/myapp/api.user.get_user to more RESTful endpoints, such as:

  • GET: https://abc.com/api/v1/user
  • POST: https://abc.com/api/v1/user

Frappe already has a REST interface.

https://docs.frappe.io/framework/user/en/api/rest

It won’t work for api.user.get_user because that endpoint is a remote procedure call, not a resource.

If you really need to refactor api methods as REST-style calls, it will take some work. You’d probably need to build a custom request router and apply it via hooks.
https://docs.frappe.io/framework/user/en/python-api/routing-and-rendering

Thanks for the link @peterg!

I was in the same situation some time back but I could not find any easy way to get restful endpoints. But seems it is quite easy to get working with a custom PageRender.

I just tried the sample from frappe.tests.test_website.CustomPageRenderer


# in hooks.py
page_renderer = "my_app.utils.CustomAPIRenderer"


# in my_app.utils.py

import frappe
from frappe.utils.response import build_response

class CustomAPIRenderer:
    def __init__(self, path, status_code=None):
        self.path = path
        self.status_code = 200

    def can_render(self):
        if self.path.startswith("api_new"):
            return True

    def render(self):
        frappe.local.response = frappe._dict({
            "path": self.path,
            "method": frappe.request.method
        })

        return build_response("json")

It works for GET and POST.

1 Like