”;
Falcon adopts RESTful architectural style. Hence it uses resource based routing. A resource class is responsible for handling the HTTP methods by the responders, which are essentially class methods with a name that starts with on_ and ends in the lowercased HTTP method name (e.g., on_get(), on_patch(), on_delete(), etc.). The add_route() method of the Falcon Application object associates its router with an instance of resource class.
In the Hellofalcon.py example used above, the on_get() and on_post() responders are invoked when the /hello route is requested by the client by GET and POST method respectively.
If no route matches the request, an instance of HTTPRouteNotFound is raised. On the other hand, if a route is matched but the resource does not implement a responder for the requested HTTP method, a default responder raises an instance of HTTPMethodNotAllowed.
Field Converters
Falcon”s routing mechanism allows URLs to pass parameters to the responders. The URL comprises of three parts: The protocol (such as http:// or https://) followed by the IP address or hostname. The remaining part of the URL after first / after the hostname is called as the path or endpoint. Parameters to be passed are after the endpoint.
This acts as a resource identifier such as a unique ID or primary key. The parameter names are enclosed in curly brackets. Value of a path parameter goes to the argument defined in the responder method in addition to request and response.
In the following example, the router associates the resource class object with a URL consisting of a parameter after the endpoint.
from waitress import serve import falcon import json class HelloResource: def on_get(self, req, resp, nm): """Handles GET requests""" resp.status = falcon.HTTP_200 resp.content_type = falcon.MEDIA_TEXT resp.text = ( ''Hello ''+nm ) app = falcon.App() hello = HelloResource() app.add_route(''/hello/{nm}'', hello) if __name__ == ''__main__'': serve(app, host=''0.0.0.0'', port=8000)
We can see that the on_get() responder method has an additional parameter nm to accept the data parsed from the URL route. Let us test http://localhost:8000/hello/Priya with HTTPie tool.
>http GET localhost:8000/hello/Priya HTTP/1.1 200 OK Content-Length: 11 Content-Type: text/plain; charset=utf-8 Date: Mon, 18 Apr 2022 12:27:35 GMT Server: waitress Hello Priya
The default data type to which the path parameters are parsed to is str (i.e. string). However, Falcon”s router engine has the following built-in field converters using which they can be read into other data types as well.
-
IntConverter − This class is defined in falcon.routing module. The constructor uses the following arguments −
IntConverter(num_digits=None, min=None, max=None)
-
num_digits − The value must have given number of digits.
-
min − minimum required value of the parameter
-
max − maximum allowed value of the parameter.
Where,
For example, the following add_route() function accepts an integer between 1 to 100 as rollno.
app.add_route(''/student/{rollno:int(1,1,100}'', StudentResource())
-
UUIDConverter − This class in the falcon.routing module gives converts a string of 32 hexadecimal digits into a UUID (Universal Unique Identifier).
-
DateTimeConverter − Converts the parameter string to a datetime variable. The parameter must be a string in any format recognized by strptime() function, the default being ”%Y-%m-%dT%H:%M:%SZ”.
Format string uses the following format codes −
%a | Abbreviated weekday name | Sun, Mon |
%A | Full weekday name | Sunday, Monday |
%d | Day of the month as a zero-padded decimal | 01, 02 |
%-d | day of the month as decimal number | 1, 2.. |
%b | Abbreviated month name | Jan, Feb |
%m | month as a zero padded decimal number | 01, 02 |
%B | Full month name | January, February |
%-y | year without century as a decimal number | 0, 99 |
%Y | year with century as a decimal number | 2000, 1999 |
%H | hour(24 hour clock) as a zero padded decimal number | 01, 23 |
%p | locale”s AM or PM | AM, PM |
%-M | Minute as a decimal number | 1, 59 |
%-S | Second as a decimal number | 1, 59 |
In the following example, the add_route() function associates a URL with two parameters with the Resource object. First parameter nm is a string by default. The second parameter age uses IntConverter.
from waitress import serve import falcon import json class HelloResource: def on_get(self, req, resp, nm,age): """Handles GET requests""" retvalue={"name":nm, "age":age} resp.body=json.dumps(retvalue) resp.status = falcon.HTTP_200 resp.content_type = falcon.MEDIA_JSON app = falcon.App() hello = HelloResource() app.add_route(''/hello/{nm}/{age:int}'', hello) if __name__ == ''__main__'': serve(app, host=''0.0.0.0'', port=8000)
Note that the on_get() responder uses the path parameters to form a dict object – retvalue. Its JSON representation is then assigned as the value of response body and returned to the client. As mentioned earlier, JSON is the default content type of Falcon”s response object.
Start the Waitress server and check the response for the URL http://localhost:8000/hello/Priya/21 with the help of HTTPie.
http GET localhost:8000/hello/Priya/21 HTTP/1.1 200 OK Content-Length: 28 Content-Type: application/json Date: Fri, 22 Apr 2022 14:22:47 GMT Server: waitress { "age": 21, "name": "Priya" }
You can also check the response in a browser as follows −
”;