Need Help?

  •   Chat on Gitter
  •   Github Issues
  •   Ask on StackOverflow - tag aahframework

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

Have a look at 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


aahframework_org {
  # domain config goes here


Used as free text for mentioning domain name.

Default value is keyname.

name = "mysampleapp routes"


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 = ""

# this is for wildcard Subdomain, don't forget mention `subdomain = true`
host = "*"


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"


Indicates the current domain section is a sub-domain.

Since v0.6 Wildcard subdomain supported.

Default value is false.

subdomain = true


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


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


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


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 config attribute value 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 parameters must 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 config attribute value is HTTP method. It can be multiple HTTP methods with comma separated. It can be lowercase or uppercase.

Default value is GET.

# Usages
method = "POST"

method = "PUT,PATCH"


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 or User
    • Best Practices: choose one format definition style and stick to it.
  • controller attribute supports both naming conventions. For e.g.: User or UserController

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 attribute is used to map defined action method from the controller for the path.

Default values are mapped based on HTTP method. Note: for multiple HTTP method mapping no default value, you have to provide one.

  • GET - action is Index
  • POST - action is Create
  • PUT - action is Update
  • PATCH - action is Update
  • DELETE - action is Delete
  • OPTIONS - action is Options
  • HEAD - action is Head
  • TRACE - action is Trace
action = "EditUser"


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.


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 routes auth attribute is not defined then framework treats that route as 403 Forbidden. * Else framework treats that route as anonymous.

Default value is empty string.

auth = "form_auth"


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"

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.

If you’re not interested in namespace/group, you can define every routes with full path as traditional approach.


Defining route within route definition to make that as namespace/group routes.

routes {
  v1_api {
    path = "/v1"

    routes {
      list_users {
        # /v1/users
        path = "/users"
        controller = "User"
        action = "List"

        # adding child routes
        # this routes section can go to create_user route too, doesn't matter
        routes {
          edit_user {
            # /v1/users/:id
            path = "/:id"
            method = "POST"
            controller = "User"
            action = "Edit"

          disable_user {
            # /v1/users/:id/settings
            path = "/:id/settings"
            controller = "User"
            action = "Disable"

      create_user {
        # /v1/users
        path = "/users"
        method = "POST"
        controller = "User"
        #action = "Create" # default value is Create