Routing#
Routing is the process of determining how to handle a request to a particular URL. In ramka it is done using two components: routes that define views that are rendered for specified URLs and a router that is responsible for determining which route should be used for a given request.
Router#
The default router used in the app is the ramka.routers.SimpleRouter
.
You can override it by setting the router
parameter while initializing the
application. Each router should inherit the ramka.routers.BaseRouter
class and implement the following methods:
add_route
- adds a route to the router. It accepts a route path (a string), a view (a function or a class, see Views to learn more), and methods that should be allowed for the route (a list of strings). See the examples below:def sample_function_view(request, response): response.text = "External route" app.add_route("/function-view", sample_function_view, methods=["GET"]) class SampleClassView(BaseView): def get(self, request, response, **kwargs): response.text = "Sample class-view GET page" app.add_route("/class-view", SampleClassView, methods=["GET", "POST"])
route
provides the same functionality asadd_route
but it is meant to be used as a decorator and therefore does not accept the view as the parameter. For example:@app.route("/function-view", methods=["GET"]) def sample_function_view(request, response): response.text = "External route" @app.route("/class-view", methods=["GET", "POST"]) class SampleClassView(BaseView): def get(self, request, response, **kwargs): response.text = "Sample class-view GET page"
has_route
can be used to check if a route with a given path has been already defined. It only takes a path as a parameter and returns a boolean.resolve
takes a path and returns aramka.routing.ResolvedRoute
object that is described in the next section.
In all examples above the methods from app
objects are used, but under the
hood they call the methods from the router. All those methods can be used
directly on the router object.
Routes and Resolved Routes#
Functions add_route
and route
described above create
ramka.routing.Route
objects underneath. These objects are used to store
information about the route and to provide a way to resolve the route for a
given request. When a route is resolved by the router it returns a
ramka.routing.ResolvedRoute
object. The only difference between the two
is that the resolved route also contains resolved dynamic parameters of the
route for the request.
For example, let’s take a look at the code below:
@app.route("/hello/{name}")
def sample_function_view(request, response, name):
response.text = f"Hello {name}!"
When the router resolves the route, it returns a
ramka.routing.ResolvedRoute
object that contains resolved name
parameter with the value.
If you want to use custom implementations of Route
and ResolvedRoute
classes then you can do that in your custom router. In the SimpleRouter
,
the Route
and ResolvedRoute
objects are created in add_route
and
resolve
methods, so you can replace them with your own implementations.
Reference implementation#
For a reference implementation of the router, see
ramka.routing.SimpleRouter
in file
ramka.routing.router
. Both ramka.routing.Route
and
ramka.routing.ResolvedRoute
classes are defined in file
ramka.routing.route
.