diff options
| author | Anhgelus Morhtuuzh <william@herges.fr> | 2025-10-02 16:04:35 +0200 |
|---|---|---|
| committer | Anhgelus Morhtuuzh <william@herges.fr> | 2025-10-02 16:04:35 +0200 |
| commit | 4cff7748af65038db3754ab9ce157d528f03a474 (patch) | |
| tree | 5e44c4494cbed703727d4a76c2f4ffb8de1083e2 | |
| parent | b5d7d7816e9b7c5e3b2598e3a1dc322580aec65b (diff) | |
feat(backend): simple http server
| -rw-r--r-- | README.md | 3 | ||||
| -rw-r--r-- | backend/router.go | 24 | ||||
| -rw-r--r-- | go.mod | 5 | ||||
| -rw-r--r-- | go.sum | 4 | ||||
| -rw-r--r-- | main.go | 57 |
5 files changed, 93 insertions, 0 deletions
@@ -32,3 +32,6 @@ This project uses a custom markdown parser. It is located in `markdown`. I made my custom parser because I have extended its specification. +The backend is in `backend`. +It uses `github.com/go-chi/chi/v5`. + diff --git a/backend/router.go b/backend/router.go new file mode 100644 index 0000000..6c7f9f8 --- /dev/null +++ b/backend/router.go @@ -0,0 +1,24 @@ +package backend + +import ( + "net/http" + "time" + + "github.com/go-chi/chi/v5" + "github.com/go-chi/chi/v5/middleware" +) + +func NewRouter() *chi.Mux { + r := chi.NewRouter() + + r.Use(middleware.Timeout(30 * time.Second)) + r.Use(middleware.Logger) + + r.Get("/", func(w http.ResponseWriter, r *http.Request) { + _, err := w.Write([]byte("Hello World")) + if err != nil { + panic(err) + } + }) + return r +} @@ -1,3 +1,8 @@ module git.anhgelus.world/anhgelus/small-world go 1.25.1 + +require ( + github.com/go-chi/chi/v5 v5.2.3 // indirect + github.com/joho/godotenv v1.5.1 // indirect +) @@ -0,0 +1,4 @@ +github.com/go-chi/chi/v5 v5.2.3 h1:WQIt9uxdsAbgIYgid+BpYc+liqQZGMHRaUwp0JUcvdE= +github.com/go-chi/chi/v5 v5.2.3/go.mod h1:L2yAIGWB3H+phAw1NxKwWM+7eUH/lU8pOMm5hHcoops= +github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= +github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= @@ -0,0 +1,57 @@ +package main + +import ( + "context" + "errors" + "log/slog" + "net/http" + "os" + "os/signal" + "syscall" + + "git.anhgelus.world/anhgelus/small-world/backend" + "github.com/joho/godotenv" +) + +func init() { + err := godotenv.Load(".env") + if err != nil && !errors.Is(err, os.ErrNotExist) { + slog.Error("loading .env", "error", err) + } +} +func main() { + r := backend.NewRouter() + + slog.Info("starting http server") + server := &http.Server{Addr: ":8000", Handler: r} + + errChan := make(chan error) + go startServer(server, errChan) + + sc := make(chan os.Signal, 1) + signal.Notify(sc, syscall.SIGINT, syscall.SIGTERM, os.Interrupt) + + ok := true + for ok { + select { + case err := <-errChan: + slog.Error("http server running", "error", err) + slog.Info("restarting the server") + go startServer(server, errChan) + case <-sc: + err := server.Shutdown(context.Background()) + if err != nil { + slog.Error("closing http server", "error", err) + } + ok = false + } + } + slog.Info("http server stopped") +} + +func startServer(server *http.Server, errChan chan error) { + err := server.ListenAndServe() + if err != nil && !errors.Is(err, http.ErrServerClosed) { + errChan <- err + } +} |
