aah Routing

aah supports domains and subdomains seamlessly. It provides route URL lookup by route name effectively.

The router is optimized for high performance and a small memory footprint. It scales well with very long paths and a large number of routes. Radix tree structure is used for efficient matching.

aah internally uses customized version of httprouter, developed by @julienschmidt.

Table of Contents

Highlights

  • URI Parameters - Give path segment a name and access it as action method parameters.
  • Perfect for RESTful APIs - Build sensible, hierarchical RESTful APIs. Router has builtin native support for OPTIONS requests and 405 Method Not Allowed replies.
  • Only explicit matches - a request can only match exactly one or no route. As a result, there are also no unintended matches, which makes it great for SEO and improves the user experience.
  • Stop caring about trailing slashes - Choose the URL style you like, the router automatically redirects the client if a trailing slash is missing or if there is one extra. Of course, it does only if the new path has a controller action. Behavior could be disabled at domain level using redirect_trailing_slash = false in the routes config.
  • Path auto-correction - Besides detecting the missing or additional trailing slash at no extra cost, the router can also fix wrong cases and remove superfluous path elements (like ../ or //). Is CAPTAIN CAPS LOCK one of your users? Router can help user by making a case-insensitive look-up and by redirecting to the correct URL.
  • Zero Garbage - The matching and dispatching process generates zero bytes of garbage. In fact, the only heap allocations that are made, is by building the slice of the key-value pairs for path parameters. If the request path contains no parameters, not even a single heap allocation is necessary.

Route Definitions

aah routes.conf is composed of four major config sections, such as domains, domain, static routes and application routes.

Learn routes configuration attributes and its purpose.

# -----------------------------------------------------------------------------
# app name - Application Routes Configuration
#
# Refer documentation to explore and configure routes.
# Doc: https://docs.aahframework.org/routing.html
# -----------------------------------------------------------------------------
domains {
  # Choose a `unique keyname` to define domain section and its configuration.
  # Tip: Use app name, domain name address, port no values to create a domain key.
  #
  # Examples: aahframework { ... }, docs_aahframework { ... }
  domain_key_name {

    #
    # Domain configurations - host, port and CORS, for example.
    #

    # Static files Routes Configuration
    # Optional section- API and WebSocket apps, as examples
    static {
      # ...
    }

    # Routes Configuration
    routes {

      # domain routes comes here

    } # end - routes

  } # end - domain configurations



  # Choose a `unique keyname` to define domain section and its configuration.
  # Tip: Use app name, domain name address, port no values to create a domain key.
  #
  # Examples: aahframework { ... }, docs_aahframework { ... }
  domain_key_name {

    #
    # Domain configurations - host, port and CORS, for example.
    #

    # Static files Routes Configuration
    # Optional section- API and WebSocket apps, as examples
    static {
      # ...
    }

    # Routes Configuration
    routes {

      # domain routes comes here

    } # end - routes

  } # end - domain configurations

} # end - all application domains

Route Constraints

Route constraints give the capability to restrict/validate route parameters (aka URI parameters) before the request sent to controller action.

# Syntax
:parameterName[constraints]

Note:

  • Constraint failure would result in 400 BadRequest via aah error handling flow.
  • Supports multiple constraints on parameter, separated by a ,. For instance: :paramName[gte=10,lte=50]
  • Data type constraints are implicit in aah

Examples

# Examples of route path parameters with constraints

#------------------------------------------------------------------------------
# Example - Data type constraints are implicit in aah
# Path              : /v1/users/:id
# Controller Action : func (u *UserController) Info(id int) { .. }

# Requests
/v1/users/10001           => pass, would reach controller action
/v1/users/myname          => fail, 400 BadRequest

#------------------------------------------------------------------------------
# Example - ISBN 13 route parameter constraint
# Path              : /v1/books/:isbn[isbn13]/excerpt
# Controller Action : func (b *BookController) Excerpt(isbn string) { .. }

# Requests - ISBN numbers taken from https://www.isbn-13.info/example
/v1/books/978-1-56619-909-4/excerpt   => pass, would reach controller action
/v1/books/9781566199094/excerpt       => pass, would reach controller action
/v1/books/1-56619-909-3/excerpt       => fail, 400 BadRequest
/v1/books/1566199093/excerpt          => fail, 400 BadRequest
/v1/books/dshgdshgdsjhgdshg/excerpt   => fail, 400 BadRequest

#------------------------------------------------------------------------------
# Example - oneof and alpha route parameter constraints
# Path              : /v1/temperature/:scale[oneof=celsius fahrenheit,alpha]
# Controller Action : func (w *WeatherController) Temperature(scale string) { .. }

# Requests
/v1/temperature/fahrenheit      => pass, would reach controller action
/v1/temperature/celsius         => pass, would reach controller action
/v1/temperature/3463543         => fail, 400 BadRequest
/v1/temperature/blabla          => fail, 400 BadRequest
#------------------------------------------------------------------------------

Supported Constraints

ConstraintDescriptionExample
alphaValidates a string contains only ASCII alpha characters:paramName[alpha]
alphanumValidates a string contains only ASCII alphanumeric characters:paramName[alphanum]
asciiValidates a string contains only ASCII characters:paramName[ascii]
numericValidates a string contains a basic numeric value. basic excludes exponents etc.:paramName[numeric]
emailValidates a string contains a valid email. NOTE: This may not conform to all possibilities of any rfc standard, but neither does any email provider accept all possibilities:paramName[email]
lenValidates - for numbers: the value is equal to the parameter given. For strings: the value length is exactly that number of characters:paramName[len=10]
maxValidates - for numbers: the value is less than or equal to the parameter given. For strings: the value length is at most that number of characters:paramName[max=10]
minValidates - for numbers: the value is greater or equal to the parameter given. For strings: the value length is at least that number of characters:paramName[min=10]
eqValidates - for strings & numbers, the value is equal to the parameter given:paramName[eq=10]
neValidates - for strings & numbers, the value is not equal to the parameter given:paramName[ne=10]
gtValidates - for numbers: the value is greater than the parameter given. For strings: the value length is greater than that number of characters:paramName[gt=10]
gteSame as ‘min’ above. Kept both to make terminology with len easier:paramName[gte=10]
ltValidates - for numbers: the value is less than the parameter given. For strings: the value length is less than that number of characters:paramName[lt=10]
lteSame as ‘max’ above. Kept both to make terminology with len easier:paramName[lte=10]
oneofValidates - for strings, ints, and uints; the value is one of the values in the parameter. The parameter should be a list of values separated by whitespace. Values may be strings or numbers:paramName[oneof=red green]
base64Validates a string value contains a valid base64 value:paramName[base64]
btc_addrValidates a string value contains a valid bitcoin address. The format of the string is checked to ensure it matches one of the three formats P2PKH, P2SH and performs checksum validation:paramName[btc_addr]
isbnValidates a string value contains a valid isbn10 or isbn13 value:paramName[isbn]
isbn10Validates a string value contains a valid isbn10 value:paramName[isbn10]
isbn13Validates a string value contains a valid isbn13 value:paramName[isbn13]
uuidValidates a string value contains a valid UUID:paramName[uuid]
uuid3Validates a string value contains a valid version 3 UUID:paramName[uuid3]
uuid4Validates a string value contains a valid version 4 UUID:paramName[uuid4]
uuid5Validates a string value contains a valid version 5 UUID:paramName[uuid5]
latitudeValidates a string value contains a valid latitude:paramName[latitude]
longitudeValidates a string value contains a valid longitude:paramName[longitude]
ssnValidates a string value contains a valid U.S. Social Security Number:paramName[ssn]
ipValidates a string value contains a valid IP Address:paramName[ip]
ipv4Validates a string value contains a valid v4 IP Address:paramName[ipv4]
ipv6Validates a string value contains a valid v6 IP Address:paramName[ipv6]
cidrValidates a string value contains a valid CIDR Address:paramName[cidr]
cidrv4Validates a string value contains a valid v4 CIDR Address:paramName[cidrv4]
cidrv6Validates a string value contains a valid v6 CIDR Address:paramName[cidrv6]
tcp_addrValidates a string value contains a valid resolvable TCP Address:paramName[tcp_addr]
tcp4_addrValidates a string value contains a valid resolvable v4 TCP Address:paramName[tcp4_addr]
tcp6_addrValidates a string value contains a valid resolvable v6 TCP Address:paramName[tcp6_addr]
udp_addrValidates a string value contains a valid resolvable UDP Address:paramName[udp_addr]
udp4_addrValidates a string value contains a valid resolvable v4 UDP Address:paramName[udp4_addr]
udp6_addrValidates a string value contains a valid resolvable v6 UDP Address:paramName[udp6_addr]
ip_addrValidates a string value contains a valid resolvable IP Address:paramName[ip_addr]
ip4_addrValidates a string value contains a valid resolvable v4 IP Address:paramName[ip4_addr]
ip6_addrValidates a string value contains a valid resolvable v6 IP Address:paramName[ip6_addr]
unix_addrValidates a string value contains a valid Unix Address:paramName[unix_addr]
macValidates a string value contains a valid MAC Address:paramName[mac]
hostnameValidates a string value is a valid Hostname according to RFC 952, RFC 1123:paramName[hostname]
fqdnValidates a string value contains a valid FQDN:paramName[fqdn]