Basic Dancer2 Routing
Tags: perl, dancer2
Published: 2020-02-16 18:35:44

# Dancer2 Routing

#### Basic Dancer2 Routing

The primary Dancer2 routes accept a URI:

```perl
get '/hello' => sub {
    return "Welcome to Dancer2 Web Application";
};
```

Dancer2 routes defined in the project_name.pm package in the Dancer2 Project folder. Dancer2 loads this file during the application startup.  You may access the following route by navigating to http://localhost:5000/hello in your browser.

Following routes method are available in the Dancer2:

```perl
get '/hello' => sub {
	# Write something here
};
post '/login' => sub { 
	# Write something here 
};
put '/foo' => sub {
	# Write something here
};
options '/options' => sub {
	# Write something here
};
del '/delete_route' => sub {
	# Write something here
};
any '/foo/bar' => sub {
	# Write something here
};
```

We may need a route that responds to multiple HTTP request type in one route.

```perl
any ['get', 'post'] => '/multiple/requests' => sub {
	# Write something here
};
```


While developing the application, we may need to pass the parameters via routes.

1. Route Parameter
2. Query Parameter
3. Body Parameter

**Route Parameter**

When the parameter is the part of the route, then we called it as route parameter.

```perl
get '/username/:name' => sub {
	my $name = route_parameters->get('name');
	return "The parameter name is : ", $name;
};
```

On the browser when we type 'http://localhost:5000/username/Ashutosh', then on the page we can see "The name is Ashutosh".

![Screenshot 2020-02-16 at 11.06.47 PM](https://user-images.githubusercontent.com/12954663/74610393-c2439600-50ea-11ea-94ea-3378825fd062.png)

Similarly, we can pass multiple route parameters using Dancer2.

**Query Parameter**

When the parameters are the par of the url instead of routes.

```perl
get '/query' => sub {
	my $name = query_parameters->get('name');
	my $email = query_parameters->get('email');
	
	return "The name is : ". $name, ". The email is : ". $email;
};
```

On the browser when we type 'http://localhost:5000/query?name=Michael&email=michael@example.com', then on the page we can see "The name is : Michael. The email is : michael@example.com".

**Body Parameters**

Body parameters are easy to figure out. When the parameter passed to the function from HTML body. For ex. from the Form. When we want user to login to the application using a login_form. Then username and password are the body parameters. If it's success, then forward to user dashboard.

```perl
post '/login' => sub {
	my $email = body_parameters->get('username');
	my $password = body_parameters->get('password');
	
	## Check the username and password from the backend.
	forward '/user/dashboard';
};
```

**Regular Expression Constraint**

Using Dancer2, we can specify the format of the type of parameters. Let's say /username/:id, In this route we want to id must be integer. Dancer2 has inbuilt [Int] function to check that.

```perl
get '/username/:id[Int]' => sub {
	# It doesn't match /username/James and throughs an error --> Fail.
	# /username/12 --> Pass
	my $user_id = route_parameter->get('id');
};
```

Similarly, if we want the parameter to be type of string, then

```perl
get '/username/:name[Str]' => sub {
	# /username/12 --> Fail
	# username/James --> Pass
	
	# Do something with the code
};
```

Ok, so let's try some date format

```perl
get '/username/:date[StrMatch[qr{\d\d-\d\d-\d\d\d\d}]]' => sub {
	# /username/21-02-2019 --> Pass
	# /username/2019-10-10 --> Fail
	my $date = route_parameter->get('date');
};
```

What if, we want to pass both name and id as parameters.

```perl
get '/username/:name[Str]/:id[Int]' => sub {
	# /username/James/12 --> Pass
	# /username/12/James --> Fail
	my $name = route_parameter->get('name');
	my $user_id = route_parameter->get('id');
};
```

Sometimes, we need to pass the wild card in the url routes. 

```perl
get '/username/*/location/:loc_name[Str]' => sub {
	# /username/foo/location/Delhi --> Pass
	# /username/bar/location/Delhi --> Pass
	# /username/location/Delhi --> Fail
	# /username/foo/location/12 --> Fail
};
```

We have covered most of the regular expression constraint routes in the Dancer2. You are not limited to use RegEx in the routes.

#### Route prefix

The `prefix` method in the application can be used to prefix each route in the group with a given URI. For example, we want to prefix all route URIs within the group with *admin*. 

```perl
prefix '/admin';

get '/users' => sub {
	# will match '/admin/users' 
}; 
```

Alternate way of using prefix

```perl
prefix '/admin' => sub {

	get '/users' => sub {
		# Will also match /admin/users
	};
	
};
```

This article only covers the basic routing. In the next tutorial, we cover some more advance Route features like templates, hooks etc. Stay tuned for updates.

Edit: @David Precious, Thanks for pointing out the typo.