-
-
Notifications
You must be signed in to change notification settings - Fork 951
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to add a uri template pattern and control it in resource? #690
Comments
It seems what you want is to manage your resources as MVC pattern. If you understand the principles of REST architecture and still want to implement what you asked, you could do the following: class Resource: def __init__(self): self.methods = { 'search': self._search, } def _search(self, req, resp): resp.body = '{"message": "Hello world!"}' resp.status = falcon.HTTP_200 def on_get(self, req, resp, method): if method not in self.methods: raise falcon.HTTPNotFound() self.methods[method](req, resp) api = falcon.API() api.add_route('/resource/{method}', Resource()) |
As @MackYoel alluded to, what you have in mind is more along the lines of an RPC architectural style, as opposed to REST. The default router in Falcon was designed with REST in mind, with resources as the central focus, relying on a uniform interface of headers, methods (GET, POST, etc.), etc. to facilitate state transitions for those resources. That being said, it is possible to use a custom router, but I suspect that will still require a good bit of wrangling to afford the RPC architectural style. |
Thanks @MackYoel |
Sorry to revive an old issue, but I didn't want to create a duplicate. Can this issue be repurposed as a feature request to add support for RPC architectures (in general, not necessarily XML-RPC or JSON-RPC)? I understand the benefits of RESTful APIs well enough but sometimes it doesn't fit. To simplify things, consider an API for a calculator: I'm new to Falcon so please forgive my ignorance, but would this be as simple as allowing class Calculator(object):
def on_get_add(self, req, resp):
resp.body = str(int(req.get_param('x')) + int(req.get_param('y')))
resp.status = falcon.HTTP_200
def on_get_subtract(self, req, resp):
resp.body = str(int(req.get_param('x')) - int(req.get_param('y')))
resp.status = falcon.HTTP_200
calc = Calculator()
api = falcon.API()
api.add_route('/add', calc, suffix='add')
api.add_route('/subtract', calc, suffix='subtract') |
Hi @goodmami ! Regarding XML-RPC, that's usually only one end point, no routing involved 🙂 Given the above mentioned suffixes, and other new features in Falcon 2.0+, IMHO it makes sense to first of all tackle this issue (as the current label is also suggesting) from the documentation perspective, and then break out routing proposals into separate issues. |
@vytas7 thanks!
Yes, I believe it worked when I wrote it. My question is if that is an anticipated use of the suffix feature, or if it is too much a hack that it might be a discouraged pattern (and if so, why?).
Is there a different pattern to enable this architecture within Falcon? To be clear, I'm using Falcon already for a RESTful service, but I have an endpoint that is decidedly more RPC-like. I'd rather not use two different libraries.
Fair enough. Happy to continue the conversation on another issue. |
Hi again @goodmami !
Let me first clarify this one. It is perfectly fine to continue the conversation rolling here. What I meant was suggesting new issues in case new Falcon features were proposed to facilitate the RPC architectural style.
Indeed, it was already released when you wrote this... We ought to release more often 🤔
Regarding too much of a hack, it is ultimately only you, the API developer, who can answer this question. The anticipated canonical use of the suffix feature is representing both a RESTful collection, and its item, with a single resource class, see, e.g., How do I implement both POSTing and GETing items for the same resource?. Generally speaking though, the feature was added to easily afford alternate routes to the same resource. You can also find the original discussion here: #584 , as well as other issues linking to it. To summarize, personally I think using suffixes this way is just fine. While Falcon is primarily about RESTful APIs, we also support cookies, multipart forms (coming up in 3.0), sinks, rewriting request path in middleware, rendering a complete response inside middleware, and more. None of these is strictly RESTful. In Falcon 3.0, the ASGI flavour of the framework will venture even further into the non-RESTful, enabling use cases such as SSE emitters and WebSocket.
As also written by @kgriffs above, another way to approach this is implementing a custom router (possibly by subclassing the default As I also hinted in my previous response though, RPC over HTTP is often implemented without even touching routing, i.e., as a single end point on |
I have a example case:
resource:
import falcon
class Resource(object):
add resource to route
api = application = falcon.API()
api.add_route('/resource', Resource())
How to setup falcon while I request to uri: /resource/search -> redirect to function search in resource ?
The text was updated successfully, but these errors were encountered: