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.

Sentry blog image

How I fixed 20 seconds of lag for every user in just 20 minutes.

Our AI agent was running 10-20 seconds slower than it should, impacting both our own developers and our early adopters. See how I used Sentry Profiling to fix it in record time.

Read more

Top comments (0)