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 #ANCHOR: handler proc handler( reqfence: RequestFence ): Future[HttpResponseRef] {.async: (raises: [CancelledError]).} = let request = reqfence.valueOr: return defaultResponse() #ANCHOR: routing 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() #ANCHOR_END: routing #ANCHOR_END: handler #ANCHOR: main 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() #ANCHOR_END: main 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 httpserver: respond(HttpRequestRef, HttpCode, ByteChar), we can easily control both the HTTP status code and the response body.