2 ms·
I'd argue just making everything POST is the correct way to do a public Api too. REST tricks you into endpoints no one really wants, or you break it anyway to s
by ryathal 2y ago
I'd argue just making everything POST is the correct way to do a public Api too. REST tricks you into endpoints no one really wants, or you break it anyway to support functionality needed. SOAP was heavy with it's request/respone, but it was absolutely correct that just sending everything as POST across the wire is easier to work with.
- porridgeraisin 2y agoYeah, I like doing this as well. And all the data goes in the request body. No query parameters. Especially when the primary intended client is an SPA, where the URL shown is decoupled with the API URL. Little bit of a memory jolt: I once built a (not for prod) backend in python as follows: write a list of functions, one for each RPC, in a file `functions.py` then write this generic function for flask: import server.functions as functions @server.post("/<method>") def api(method: str): data: Any = request.json if request.is_json else {} fn = lookup(functions, method) if fn is None: return {"error": "Method not found."} return fn(data) And `lookup()` looks like: def lookup(module: ModuleType, method: str): md = module.__dict__ mn = module.__name__ is_present = method in md is_not_imported = md[method].__module__ == mn is_a_function = inspect.isfunction(md[method]) if is_present and is_not_imported and is_a_function: return md[method] return None So writing a new RPC is just writing a new function, and it all gets automatically wired up to `/api/function_name`. Quite nice. The other nice feature there was automatic "docs" generation, from the python docstring of the function. You see, in python you can dynamically read the docstring of an object. So, I wrote this: def get_docs(module: ModuleType): md = module.__dict__ mn = module.__name__ docs = "" for name in md: if not inspect.isfunction(md[name]) or md[name].__module__ != mn: continue docs += md[name].__doc__ + "\n<br>\n" return docs[:-6] Gives a simple text documentation which I served at an endpoint. Of course you could also write the docstring in openapi yaml format and serve it that way too. Quite cursed overall, but hey, its python. One of the worst footguns here is that you could accidentally expose helper functions, so you have to be sure to not write those in the functions file :P
- jitl 2y agoUse a decorator to expose functions explicitly, otherwise sounds like security issue waiting to happen. All your decorator needs to do is add the function to an __exposed__ set, then when you’re looping over the dict, only expose keys who’s values are in the __exposed__ set
- porridgeraisin 2y agoGood idea Although I suppose using an approach like mine precludes any notion of a serious application.
- curt15 2y agoSome of the AWS APIs work this way too. See for example the Cloudwatch API: https://docs.aws.amazon.com/AmazonCloudWatch/latest/APIReference/Welcome https://docs.aws.amazon.com/AmazonCloudWatch/latest/APIRefer..., which is really JSON-RPC, not REST.