Handling Multiple Routes
Goal: Learn how to handle different request paths in your HTTP server.
Source code: chapter2/src/dashboard.nim
Our first server version could only respond with one message regardless of the URL. Real-world applications usually need to handle multiple routes.
Let's update our server to handle different paths differently:
import chronos/apps/http/httpserver
proc handler(
reqfence: RequestFence
): Future[HttpResponseRef] {.async: (raises: [CancelledError]).} =
let request = reqfence.valueOr:
return defaultResponse()
try:
case request.uri.path
of "/":
await request.respond(Http200, "Welcome to the Status Dashboard!")
of "/status":
await request.respond(Http200, "The server is operational.")
else:
await request.respond(Http404, "Page not found.")
except HttpWriteError:
defaultResponse()
proc main() {.async: (raises: [TransportAddressError, CancelledError]).} =
let
address = initTAddress("127.0.0.1:8080")
server = HttpServerRef.new(address, handler).valueOr:
echo "Unable to start HTTP server: " & error
return
server.start()
echo "HTTP server running on http://127.0.0.1:8080"
try:
await server.join()
finally:
await server.stop()
await server.closeWait()
when isMainModule:
waitFor main()
To test the routes, run the project with nimble run and try visiting these URLs in your browser:
Routing Logic
The change is how we process the incoming request in the handler:
try:
case request.uri.path
of "/":
await request.respond(Http200, "Welcome to the Status Dashboard!")
of "/status":
await request.respond(Http200, "The server is operational.")
else:
await request.respond(Http404, "Page not found.")
except HttpWriteError:
defaultResponse()
We use a case statement to check the request.uri.path.
- For the root path
/, we return a welcome message. - For the
/statuspath, we return a simple operational message. - For any other path, we use the
elsebranch to return an HTTP 404 Not Found error.
By using request.respond, we can easily control both the HTTP status code and the response body.