Http Server in Nim

Here’s the translation of the HTTP server example from Go to Nim, formatted in Markdown suitable for Hugo:

Our HTTP server example demonstrates how to create a basic server using Nim’s asynchttpserver module.

import asynchttpserver, asyncdispatch
import strformat

# A fundamental concept in HTTP servers is handlers. In Nim, we can define
# handlers as asynchronous procedures that take a Request object and return
# a Future[void].

proc hello(req: Request) {.async.} =
  # The handler uses the Request object to access information about the
  # incoming request and sends a response using the `respond` method.
  # Here our simple response is just "hello\n".
  await req.respond(Http200, "hello\n")

proc headers(req: Request) {.async.} =
  # This handler does something a little more sophisticated by reading all
  # the HTTP request headers and echoing them into the response body.
  var response = ""
  for (name, value) in req.headers.pairs:
    response.add(&"{name}: {value}\n")
  await req.respond(Http200, response)

proc main() {.async.} =
  # We create a new HTTP server instance.
  var server = newAsyncHttpServer()
  
  # We set up the server routes using a case statement in the handler.
  proc handler(req: Request) {.async.} =
    case req.url.path
    of "/hello":
      await hello(req)
    of "/headers":
      await headers(req)
    else:
      await req.respond(Http404, "Not found")

  # Finally, we start the server on port 8090.
  waitFor server.serve(Port(8090), handler)

# Run the main procedure
waitFor main()

To run the server:

$ nim c -r http_server.nim

Access the /hello route:

$ curl localhost:8090/hello
hello

This example demonstrates how to create a basic HTTP server in Nim. It uses the asynchttpserver module, which provides an asynchronous HTTP server implementation. The server defines two routes: /hello and /headers, each with its own handler.

The hello handler simply responds with “hello\n”, while the headers handler echoes back all the request headers.

In Nim, we use asynchronous procedures (marked with .async) to handle requests efficiently. The waitFor procedure is used to run asynchronous code in a synchronous context, which is necessary for the main procedure.

Unlike Go, where the http.HandleFunc is used to register handlers, in Nim we use a case statement in the main handler to route requests to the appropriate sub-handler based on the URL path.

The server is started by calling server.serve with the port number and the main handler. This is roughly equivalent to Go’s http.ListenAndServe.

Remember to compile and run the Nim program to start the server, then you can interact with it using tools like curl as shown in the example.