Discuss or ask a question
Routing in Tales
There are two approaches to define routes. You can define a route using the @Route facet right on a method or you can define your routes in the RouteDef.fan file. Each method has its own pros and cons.
Let's start with a simple route. Create a new application. Open Index.fan and write the following code:
class Index : Page{
  @Route{uri="/test"}
  Void main(){
    response.writeStr("Hello dude")
  }
}
Now open your browser and go to http://localhost:8000/test. You can see "Hello dude" printed on screen
Get and Post Parameters
The parameters are automatically mapped to method arguments for eg., this method:
 @Route{uri="/test"}
Void main(Str name){
  response.writeStr("Hello $name")
}
and in your browser go to url http://localhost:8080/test?name=Kaushik, You should see Hello Kaushik in the output. This is also true for post parametes. For eg., Try creating an html with a form posting to url "/test" and with a input text with name "name" like this
<form action="/test" method="post">
  <input type="text" name="name" />
  <input type="submt" />
</form>
The post parameters are mapped to correct variables too.
Path parameters
You can also define path parameters
@Route{uri="/test/{name}"}
Void main(Str name){
}
and this method will match a url like /test/Kaushik and name will be mapped to "Kaushik".
it is possible to define the types of the path variables. for eg., @Route{uri="/test/{name:$int}"} will only match /test/1 and not /test/abcd.
like wise you can also define $str and $bool. The types can be any valid regular expression. For eg., instead of $int you can define
@Route{uri="/test/{name:[0-9]+"}
and this will match only numbers after /test/.
You can also define a route to match only specific request methods for eg.,
@Route{uri="/test"; method=RequestMethod.post}
will only match post requests. To match any request, just don't set a method or set RequestMethod.any
Externalizing routes
Defining routes along with methods as facets is cool and quick, but it has the following disadvantages
  1. Does not clearly define the order in which routes will be picked up
  2. You cannot see all the routes that your app defines in one place.
If you want to externalize your routes, open fan/RoutesDef.fan and define a route like this
using tales
class RoutesDef : tales::RoutesDef{
  override Void main(){
    add(Route{uri="/test"; toMethod=Test#.method("main")})
  }
}
Note that Route definition is almost same except that along with the uri you should define a "toMethod"(which is obvious since tales cannot figure out the method from the facet)