# Routing

# Introduction

Routes enable the outside world to interact with your app via URLs. The most basic ExpressWebJs routes accept a URI and a closure, providing a very simple way of defining routes and behavior.

Routes are registered inside the Routes directory file.

# Basic Routing

The most basic route binding requires a URL and a closure:

Route.get("/", () => {
  "Hello World";
});

The return value of the closure will be sent back to the client as a response.

# Controller Route

You can also bind a route to a controller using a controller@method signature:

Route.get("users", "UserController@index");

The above signature UserController@index refers to the App/Http/Controller/UserController.ts index method.

# Sub Route Folder

To create a route folder to house a particular route group, use the command:

 ts-node maker make-route [ROUTE_NAME]

# Available Route Methods

The router allows you to register routes that respond to any HTTP verb:

Route.all($url, $callback);
Route.get($url, $callback);
Route.post($url, $callback);
Route.put($url, $callback);
Route.patch($url, $callback);
Route.delete($url, $callback);
Route.match($httpMethods, $uri, $callback);
Route.redirect($from, $to, $statusCode);

# Route Groups

Sometimes you may need to register some routes within a group. This allows you to share route attributes, such as URL segments and middleware, across a large number of routes without needing to define those attributes on each individual route.

Shared attributes are specified in an array format as the first parameter to the Route.group method.

Route.group({ prefix: "user" }, () => {
  Route.get("/", (req: Request, res: Response) => {
    // This translates to http://127.0.0.1:5100/api/user
  });

  Route.get("/profile", (req: Request, res: Response) => {
    // This translates to http://127.0.0.1:5100/api/user/profile
  });
});

# Middleware

Middleware are applied to all routes within the group by defining the list of middleware with the middleware parameter on the group attribute array. Middleware will be executed in the order you define this array:

Route.group({ middleware: ["auth", "admin"] }, () => {
  Route.get("/", (req: Request, res: Response) => {
    // Has auth and admin middleware
  });

  Route.get("user/profile", (req: Request, res: Response) => {
    // Has auth and admin middleware
  });
});

# Route Prefixing

A group of routes may be prefixed by using the prefix option in the attributes array of a group:

Route.group({ prefix: "admin" }, () => {
  Route.get("users", (req: Request, res: Response) => {
    // Matches The "/admin/users" URL
  });
});

# Route Parameters

You can define dynamic routes using route parameters. For example, you may need to capture a user's ID from the URL. You may do so by defining route parameters:

Route.get("/user/:id", "UserController@show");

You may define as many route parameters as required by your route:

Route.get("/posts/:id/likes/:likesId", "PostController@show");

Since the hyphen (-) and the dot (.) are interpreted literally, they can be used along with route parameters for useful purposes.

Route.get("/flights/:from-:to", "FlightController@show");

# Optional parameters

Occasionally you may need to specify a route parameter that may not always be present in the URI. You may do so by placing a ? mark after the parameter name. Make sure to give the route's corresponding variable a default value:

Route.get("/user/:name?", "UserController@show");

# Regular Expression

To have more control over the exact string that can be matched by a route parameter, you can append a regular expression in parentheses (()):

Route.get("/user/:userId(d+)", "UserController@show");

# Route Match

Sometimes you may need to register a route that responds to multiple HTTP verbs. You may do so using the match method. Or, you may even register a route that responds to all HTTP verbs using the all method:

Route.match(["get", "post"], "/books", (req: Request, res: Response) => {
  res.status(200).send("Books  route");
});

# Route Redirect

If you are defining a route that redirects to another URI, you may use the Route::redirect method. This method provides a convenient shortcut so that you do not have to define a full route or controller for performing this task.

Route.redirect("source_url", "destination_url");

# gRPC route

you can register gRPC route with Route.grpc. This takes in the proto service name as the first argument, in this case TodoService, followed by an object whose key is the rpc name.

Example:


syntax = "proto3";

package Todo;

service TodoService {
    rpc GetAllTodos(Void) returns (TodoList) {}
}

message Void{}

message TodoModel {
    string     id = 1;
    string     name = 2;
    string     isCompleted=3;
    string  created_at = 4;
    string  updated_at = 5;
}

message TodoList {
    bool       status = 1;
    string     message = 2;
    repeated   TodoModel  data = 3;
}
Route.grpc("TodoService", { GetAllTodos: "TodoController@getAllTodos" });

For the full gRPC setup in ExpressWebJs, refer to gRPC tutorial section