✎ Edit on GitHub

# Basic Routing

Routing is one of the most critical parts of a web framework. The router decides which requests get which responses.

Vapor has a plethora of functionality for routing including route builders, groups, and collections. In this section, we will look at the basics of routing.

## Register

The most basic route includes a method, path, and closure.

    drop.get("welcome") { request in
        return "Hello"
    }

The standard HTTP methods are available including `get`, `post`, `put`, `patch`, `delete`, and `options`.

    drop.post("form") { request in
        return "Submitted with a POST request"
    }

You can also use `any` to match all methods.

## Nesting

To nest paths (adding `/`s in the URL), simply add commas.

    drop.get("foo", "bar", "baz") { request in
        return "You requested /foo/bar/baz"
    }

You can also use `/`, but commas are often easier to type and work better with type safe route parameters.

## Alternate

An alternate syntax that accepts a `Method` as the first parameter is also available.

    drop.add(.trace, "welcome") { request in
        return "Hello"
    }

This may be useful if you want to register routes dynamically or use a less common method.

## Request

Each route closure is given a single Request. This contains all of the data associated with the request that led to your route closure being called.

## Response Representable

A route closure can return in three ways:

- `Response`
- `ResponseRepresentable`
- `throw`

### Response

A custom Response can be returned.

    drop.get("vapor") { request in
        return Response(redirect: "http://vapor.codes")
    }

This is useful for creating special responses like redirects. It is also useful for cases where you want to add cookies or other items to the response.

### Response Representable

As you have seen in the previous examples, `String`s can be returned in route closures. This is because they conform to ResponseRepresentable

A lot of types in Vapor conform to this protocol by default:

- String
- Int
- JSON
- Model

    drop.get("json") { request in
        return try JSON(node: [
            "number": 123,
            "text": "unicorns",
            "bool": false
        ])
    }

> If you are curious about what `node:` means, read more about Node

### Throwing

If you are unable to return a response, you may `throw` any object that conforms to `Error`. Vapor comes with a default error enum `Abort`.

    drop.get("404") { request in
        throw Abort.notFound
    }

You can customize the message of these errors by using `Abort`

    drop.get("error") { request in
        throw Abort.custom(status: .badRequest, message: "Sorry 😱")
    }

These errors are caught by default in the `AbortMiddleware` where they are turned into a JSON response like the following.

    {
        error: true,
        message: "<the message>"
    }

If you want to override this behavior, remove the `AbortMiddleware` from the `Droplet`'s middleware and add your own.

## Fallback

Fallback routes allow you to match multiple layers of nesting slashes.

    app.get("anything", "*") { request in
        return "Matches anything after /anything"
    }

For example, the above route matches all of the following and more:

- /anything
- /anything/foo
- /anything/foo/bar
- /anything/foo/bar/baz
- ...