DEV Community

Alexander Demin
Alexander Demin

Posted on

"Hello World" in HTTP way

Problem statement

Implement a "Hello World" application in any programming language of your liking.

The application is a CLI application. It first launches an HTTP server on "localhost:8000." The server should respond with a text response (content-type "text/plain") and response code 200 on any route. When the HTTP service is ready, the application sends a GET request to its HTTP server, reads the response ("Hello World"), and prints the response to the standard output. Finally, the application shuts down the HTTP server and exists.

The application can be tested by curl http://localhost:8000.

Implementation in Go

package main

import (
    "fmt"
    "io"
    "log"
    "net/http"
)

func handler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hello, World!")
}

func main() {
    http.HandleFunc("/", handler)
    go func() {
        err := http.ListenAndServe(":8000", nil)
        if err != nil {
            log.Fatalf("http.ListenAndServe failed: %v", err)
        }
    }()
    r, err := http.Get("http://localhost:8000/")
    if err != nil {
        log.Fatalf("http.Get failed: %v", err)
    }
    defer r.Body.Close()
    t, err := io.ReadAll(r.Body)
    if err != nil {
        log.Fatalf("io.ReadAll failed: %v", err)
    }
    fmt.Println(string(t))
}
Enter fullscreen mode Exit fullscreen mode

Implementation in Go with graceful HTTP server shutdown

package main

import (
    "fmt"
    "io"
    "log/slog"
    "net/http"
    "os"
)

func handler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hello, World!")
}

func configureLogging() {
    programLevel := new(slog.LevelVar)

    logger := slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: programLevel}))
    slog.SetDefault(logger)

    if os.Getenv("DEBUG") != "" {
        programLevel.Set(slog.LevelDebug)
    }
}

func main() {
    configureLogging()

    http.HandleFunc("/", handler)

    addr := "localhost:8000"
    server := &http.Server{Addr: addr}

    done := make(chan struct{})
    go func(done chan<- struct{}) {
        slog.Debug("server.ListenAndServe", "addr", addr)
        err := server.ListenAndServe()
        if err != nil {
            slog.Debug("server.ListenAndServe", "error", err)
        }
        close(done)
    }(done)

    r, err := http.Get("http://" + addr)
    if err != nil {
        slog.Error("http.Get failed", "error", err)
        return
    }
    defer r.Body.Close()
    t, err := io.ReadAll(r.Body)
    if err != nil {
        slog.Error("io.ReadAll failed", "error", err)
        return
    }
    fmt.Println(string(t))
    err = server.Shutdown(nil)
    if err != nil {
        slog.Error("server.Shutdown failed", "error", err)
        return
    }
    <-done
}
Enter fullscreen mode Exit fullscreen mode

Implementation in Typescript

Bun

import process from "node:process";

Bun.serve({ fetch: () => new Response("Hello World!"), port: 8000 });

console.log(await (await fetch("http://localhost:8000/")).text());
process.exit();
Enter fullscreen mode Exit fullscreen mode

Deno

Deno.serve(
  { port: 8000, onListen: () => {} }, 
  () => new Response("Hello World!")
);
console.log(await(await fetch("http://localhost:8000/")).text());
Deno.exit();
Enter fullscreen mode Exit fullscreen mode

The challenge for you is how you would implement this.

Top comments (0)