From 4cff7748af65038db3754ab9ce157d528f03a474 Mon Sep 17 00:00:00 2001 From: Anhgelus Morhtuuzh Date: Thu, 2 Oct 2025 16:04:35 +0200 Subject: feat(backend): simple http server --- README.md | 3 +++ backend/router.go | 24 +++++++++++++++++++++++ go.mod | 5 +++++ go.sum | 4 ++++ main.go | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 93 insertions(+) create mode 100644 backend/router.go create mode 100644 go.sum create mode 100644 main.go diff --git a/README.md b/README.md index 1eddd2b..4f7af90 100644 --- a/README.md +++ b/README.md @@ -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 +} diff --git a/go.mod b/go.mod index 37b3f25..38c749b 100644 --- a/go.mod +++ b/go.mod @@ -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 +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..fe271b4 --- /dev/null +++ b/go.sum @@ -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= diff --git a/main.go b/main.go new file mode 100644 index 0000000..a277761 --- /dev/null +++ b/main.go @@ -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 + } +} -- cgit v1.2.3