aah Routes Configuration
aah Routes configuration is flexible and effective. The configuration syntax is used by aah framework is very similar to HOCON syntax. To learn more about configuration syntax.
Reference to App Config, Security Config, Log Config.
Table of Contents
- domains { … }
- domain { … }
- name
- host
- port
- subdomain
- redirect_trailing_slash
- method_not_allowed
- auto_options
- default_auth Since v0.7
- cors { … } Since v0.10
- not_found { … } On v0.8 removed, in-favor of Centralized Error Handler
- static { … }
- routes { … }
- path
- method
- controller
- action
- auth Since v0.7
- max_body_size Since v0.8
- anti_csrf_check Since v0.9
- Namespace/Group routes { … }
- domain { … }
Have a look at aahframework.org routes configuration. It is simple one, it gives an idea on how you can do it for your application.
Section: domains { … }
Domain and sub-domain configuration goes into section domains { ... }
.
Section: unique keyname - user defined
Pick your choice of an unique keyname
to define your domain section in the routes configuration.
No default value.
localhost {
# domain config goes here
}
#OR
aahframework_org {
# domain config goes here
}
name
Used as free text for mentioning domain name.
Default value is keyname
.
name = "mysampleapp routes"
host
aah framework supports multi-domain routes configuration out-of-the-box. host
used to determine routes of domain and processing the incoming request.
Since v0.6 Wildcard subdomain is supported.
It is required, no default value.
host = "localhost"
host = "aahframework.org"
# this is for wildcard Subdomain, don't forget mention `subdomain = true`
host = "*.aahframework.org"
port
aah framework supports multi-domain routes configuration out-of-the-box. Port is used to determine domain routes for the incoming request. This is useful when you have proxy server in-front of aah application.
For port 80
and 443
, put empty string or actual value.
Default value is 8080.
port = "80"
subdomain
Indicates the current domain section is a sub-domain.
Since v0.6 Wildcard subdomain supported.
Default value is false
.
subdomain = true
redirect_trailing_slash
Redirect trailing slash is to enable automatic redirection if the current route can’t be matched but a route
for the path with (without) the trailing slash exists.
For e.g.: if /foo/
is requested but a route only exists for /foo
, the client is redirected to /foo
with http status code 301
for GET
requests and 307
for all other request methods as per RFC7231
.
Default value is true
.
redirect_trailing_slash = true
method_not_allowed
405 MethodNotAllowed
reply is supported out-of-the-box status with HTTP Header Allow
as per RFC7231
. Perfect for RESTful APIs.
The router checks if another method is allowed for the current route, if the current request can not be routed. If this is the case, the request is answered with MethodNotAllowed
and HTTP status code 405
. If no other Method is allowed, the request is delegated to the not_found
controller if defined otherwise default one.
Default value is true
.
method_not_allowed = true
auto_options
OPTIONS
request auto replies supported out-of-the-box. User defined OPTIONS
routes take priority over the automatic replies. Perfect for RESTful APIs.
Default value is true
.
auto_options = true
default_auth
Since v0.7 Default auth is used when route does not have attribute auth
defined.
Default value is empty string.
default_auth = "form_auth"
Section: not_found { … }
On v0.8 configuration is removed in-favor of Centralized Error Handler.
Define your custom NotFound
implementation. It is invoked when no matching route is found. If not defined default one is invoked. This is optional section.
Create your controller and action of your choice. Then register in the routes config. You may call IsStaticRoute()
in the NotFound action to know whether the incoming request is static or application route
.
controller
and action
is required value if not_found
section is defined.
not_found {
controller = "App"
action = "NotFound"
}
Section: routes { … }
Routes section is used to define application routes. It is easy to Individual routes or namespace/group routes.
Each route definition has config attributes called path
, method
controller
, and action
. Some has default value if it’s not set.
Pick your choice of unique name
for each route definition. It is called as route name
and used for Reverse URL generation.
Sample route definition:
# Usages
register_user { # route name, it is used for reverse route
# route config goes here
}
edit_user { # route name, it is used for reverse route
# route config goes here
}
path
Path config attribute is used to match incoming request by router. It can contain two types of parameters:
:name
- Named parameter : It is dynamic path segments. They match anything until the next/
or the path end. For e.g.:/blog/:category/:post
*name
- Catch-all parameter : It match anything until the path end, including the directory index (the/
before the catch-all). Since they match anything until the end, catch-all parametersmust
always be the final path element. For e.g.:/assets/*filepath
Note: path
must begin with /
.
It is required, no default value.
# Usages
path = "/users/:userId/profile"
path = "/users/:userId"
path = "/users"
method
Method config attribute is used to map HTTP
method verb. It can be lowercase or uppercase.
Default value is GET
.
# Usages
method = "POST"
method = "PATCH"
controller
controller
attribute is used to map controller to be called for the mapped URL definition in the path
.
controller
attribute supports with or without package prefix. For e.g.:v1/User
orUser
- Best Practices: choose one format definition style and stick to it.
controller
attribute supports both naming conventions. For e.g.:User
orUserController
It is required, no default value.
# Usages
# Best Practices: choose one format of definition style and stick to it.
controller = "User"
controller = "UserController"
controller = "v1/User"
controller = "v1/UserController"
action
action
attribute is used to map defined action method from the controller for the path
.
Default values are mapped based on HTTP
method.
GET
- action isIndex
POST
- action isCreate
PUT
- action isUpdate
PATCH
- action isUpdate
DELETE
- action isDelete
OPTIONS
- action isOptions
HEAD
- action isHead
TRACE
- action isTrace
action = "EditUser"
auth
Since v0.7 Auth config attribute is used to assign auth scheme for the route. If you do not set this attribute then framework acquire value as follows.
- Inherits the parent route
auth
attribute if present. - Inherits the
default_auth
attribute config value if defined. - Otherwise it becomes not defined.
Note: When routes auth
attribute is not defined; two possible actions are taken:
- If one or more auth schemes are defined in
security.auth_schemes { ... }
and routesauth
attribute is not defined then framework treats that route as403 Forbidden
. - Else framework treats that route as
anonymous
.
Default value is empty string.
auth = "form_auth"
max_body_size
Since v0.8 Max request body size for this particular route. This is override value of request.max_body_size
from aah.conf.
Default value is 0mb
. Global default value in aah.conf is 5mb
.
max_body_size = "100mb"
anti_csrf_check
Since v0.9 Optionally you can disable Anti-CSRF check for particular route. There are cases you might need this option. In-general don’t disable the check.
This attribute is not applicable for REST APIs even if its defined.
Default value is true
.
anti_csrf_check = false
Namespace/Group routes { … }
Configuring namespace/group routes is very easy to define. Simply define routes
within route definition to make that as namespace/group routes.
Nested routes config works like this:
routes {
<route_name1> { # unique route name
# this route attributes
# child routes - level 1
routes {
<route_name11> { # unique route name
# this route attributes
# child routes - level 2
routes {
<route_name111> { # unique route name
# you can go on any level with your creativity
}
}
}
}
}
<route_name2> { # unique route name
# same as above
}
}
Pro Tips for nested/namespace routes
path
- if its not provided in the child route then inherits parent value as-is (Since v0.10) otherwise prefix to child pathmethod
- provided value otherwise default value is GETcontroller
- if its not provided in the child route then inherits parent value as-is Since v0.10action
- if its not provided then action value is chosen based on HTTP methodauth
- if its not provided in the child route then inherits parent value as-ismax_body_size
- if its not provided thenrequest.max_body_size
config value is used fromaah.conf
anti_csrf_check
- default is true for web application, for REST API this doesn’t take effect even if its defined
Sample of mapping nested routes
- Sample 1: On GitHub, I have provided one of the suggestion for Web and API routes together see here
Sample 2: Let’s say following URLs into routes definition
# Let's say you have controller `UserController` and
# it has actions `List`, Index, `Create`, `Update`, `Delete`, `Settings` and `UpdateSettings`.
# URLs are:
Get Users - GET /v1/users
Create User - POST /v1/users
Get User - GET /v1/users/:id
Update User - PATCH /v1/users/:id
Delete User - DELETE /v1/users/:id
Get User Settings - GET /v1/users/:id/settings
Update User Settings - PATCH /v1/users/:id/settings
Configuration: This is to demonstrate the nested/group/namespace routes. Always go with your creativity.
routes {
v1_api {
path = "/v1"
routes {
# /v1/users
users {
path = "/users"
controller = "User"
action = "List"
routes {
# /v1/users
create_user {
method = "POST"
}
routes {
path = "/:id"
routes {
get_user {
# Inherits from parents
}
# /v1/users/:id
update_user {
method = "PATCH"
}
# /v1/users/:id
delete_user {
method = "DELETE"
}
# /v1/users/:id/settings
get_user_settings {
path = "/settings"
action = "Settings"
}
# /v1/users/:id/settings
update_user_settings {
path = "/settings"
method = "PATCH"
action = "UpdateSettings"
}
}
}
}
} # end users routes
}
} # end v1_api
}