Defining a Fallback Route


(Jon Wallace) #1

Hello,

I'm looking for some clarification on defining a fallback route, basically to avoid the default not found situation. I believe my understanding is correct but wanted to double-check.

So my understanding with routes is that they get put into an array and when requested, the first one is used to handle the request. So in the example below, the response would be Route 2 when / is requested?

router.get("/") { _, response, next in
    response.headers["Content-Type"] = "text/plain; charset=utf-8"
    try response.send("Route 2").end()
}

router.get("/") { _, response, next in
    response.headers["Content-Type"] = "text/plain; charset=utf-8"
    try response.send("Route 1").end()
}

With this in mind, is it acceptable to have a final fallback at the end to handle anything else - for example:

router.get() { _, response, next in
    response.status(HTTPStatusCode.notFound)
    response.headers["Content-Type"] = "text/plain; charset=utf-8"
    try response.send("Fallback Route").end()
}

Would this be acceptable, or can anyone see any issues with this approach?

Thanks in advance!
Jon


(Nocturnal) #2

There's a major issue with your code which is going to affect how you see things. You need to remember to call next() at the end of your route handlers, unless there's some reason that you need to completely stop the response process from continuing. Similarly, you should only call .end() if you really need to.

On a more minor note, response.headers has a setType() method which is more pleasant to use to set a Content-Type header.

So rewriting your first code sample a bit:

router.get("/") { _, response, next in
    response.headers.setType("text/plain", charset: "utf-8")
    response.send("Route 2")
    next()
}

router.get("/") { _, response, next in
    response.headers.setType("text/plain", charset: "utf-8")
    response.send("Route 1")
    next()
}

With your route handlers written as such, visiting the "/" path will actually cause both handlers to be executed in sequence, so the output will be "Route 2Route 1". Basically any route handler (or middleware handler) which can match the incoming path will be executed.

Given this, if you define a handler with .get() with a blank path parameter, that handler will actually be executed for any incoming GET request. This may or may not be what you want, but if you're intending to set a handler to show the user a 404 message, you would want that handler to fire for all types of requests, not just GET ones. Check out how the Kitura-Sample app does it. Also, I'll toot my own horn and point you to the Routers chapter of my Kitura book for more general info on how Router and route handlers work.