Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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 /status path, we return a simple operational message.
  • For any other path, we use the else branch 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.