Skip to content

Commit

Permalink
feat: base web server with healthz endpoint and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
logan-bobo committed May 25, 2024
1 parent 9a67ee6 commit fc02a17
Show file tree
Hide file tree
Showing 10 changed files with 172 additions and 0 deletions.
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,10 @@

# Go workspace file
go.work


# env file
.env

# binary
url-short
29 changes: 29 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
FROM alpine:3.20.0 AS base

RUN apk update
RUN apk upgrade
RUN apk add --update go=1.22.3-r0

FROM base AS tester

WORKDIR /opt/url-short

ADD . /opt/url-short

CMD ["go", "test"]

FROM base AS builder

WORKDIR /build

ADD . /build

RUN go build -o main .

FROM builder AS production

WORKDIR /opt/url-short/

COPY --from=builder /build/main .

CMD ["./main"]
29 changes: 29 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
fmt:
go fmt ./...
.PHONY:fmt

lint: fmt
golangci-lint run -v
.PHONY:lint

vet: lint
go vet ./...
.PHONY:vet

build:
docker build . -t "url-short:latest"
.PHONY:build

run:
docker compose up -d
.PHONY:run

stop:
docker compose down
.PHONY:stop

test:
docker build . -t "url-short:test" --target tester
docker run -t "url-short:test"
.PHONY:test

9 changes: 9 additions & 0 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
version: '3.1'

services:
url-short:
image: url-short:latest
env_file:
- .env
ports:
- 5001:8080
3 changes: 3 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module url-short

go 1.22.3
Empty file added go.sum
Empty file.
15 changes: 15 additions & 0 deletions handlers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package main

import "net/http"

type apiConfig struct{}

func (apiCfg *apiConfig) healthz(w http.ResponseWriter, r *http.Request) {
payload := struct {
Status string `json:"status"`
}{
Status: "ok",
}

respondWithJSON(w, http.StatusOK, payload)
}
25 changes: 25 additions & 0 deletions handlers_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package main

import (
"net/http"
"net/http/httptest"
"testing"
)

func TestHealthEndpoint(t *testing.T){
t.Run("test healthz endpoint", func(t *testing.T){
request, _ := http.NewRequest(http.MethodGet, "/api/v1/healthz", nil)
response := httptest.NewRecorder()

apiCfg := apiConfig{}

apiCfg.healthz(response, request)

got := response.Body.String()
want := `{"status":"ok"}`

if got != want {
t.Errorf("got %q wanted %q", got, want)
}
})
}
30 changes: 30 additions & 0 deletions httphelper.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package main

import (
"encoding/json"
"log"
"net/http"
)

func respondWithJSON(w http.ResponseWriter, status int, payload interface{}) {
data, err := json.Marshal(payload)

if err != nil {
log.Printf("can not Marshal payload %v", payload)
return
}

w.Header().Set("content-type", "application/json")
w.WriteHeader(status)
w.Write(data)
}

func respondWithError(w http.ResponseWriter, code int, msg string) {
errorResponse := struct {
Error string `json:"error"`
}{
Error: msg,
}

respondWithJSON(w, code, errorResponse)
}
25 changes: 25 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package main

import (
"log"
"net/http"
"os"
)

func main() {
serverPort := os.Getenv("SERVER_PORT")

mux := http.NewServeMux()

server := &http.Server{
Addr: ":" + serverPort,
Handler: mux,
}

apiCfg := apiConfig{}

mux.HandleFunc("GET /api/v1/healthz", apiCfg.healthz)

log.Printf("Serving port : %v \n", serverPort)
log.Fatal(server.ListenAndServe())
}

0 comments on commit fc02a17

Please sign in to comment.