Skip to content
This repository was archived by the owner on Apr 25, 2025. It is now read-only.

Commit 5c60a89

Browse files
committed
feat: separate routes from main.go and create an app struct
1 parent 9fde0fe commit 5c60a89

File tree

5 files changed

+73
-24
lines changed

5 files changed

+73
-24
lines changed

cmd/web/handlers.go

+10-12
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,12 @@ package main
33
import (
44
"fmt"
55
"html/template"
6-
"log"
76
"net/http"
87
"strconv"
98
)
109

11-
// Define a home handler function which writes a byte slice containing
12-
// "Hello from Snippetbox" as the response body.
13-
func home(w http.ResponseWriter, r *http.Request) {
10+
// change the signature of the home handler so it is defined as a method against *application
11+
func (app *application) home(w http.ResponseWriter, r *http.Request) {
1412

1513
if r.URL.Path != "/" {
1614
http.NotFound(w, r)
@@ -26,39 +24,39 @@ func home(w http.ResponseWriter, r *http.Request) {
2624
ts, err := template.ParseFiles(files...)
2725

2826
if err != nil {
29-
log.Print(err.Error())
30-
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
27+
app.logger.Error(err.Error(), "method", r.Method, "uri", r.URL.RequestURI())
28+
app.serverError(w, r, err)
3129
return
3230
}
3331

3432
err = ts.ExecuteTemplate(w, "base", nil)
3533

3634
if err != nil {
37-
log.Print(err.Error())
38-
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
35+
app.logger.Error(err.Error(), "method", r.Method, "uri", r.URL.RequestURI())
36+
app.serverError(w, r, err)
3937
}
4038

4139
}
4240

4341
// Add a snippetView handler function.
44-
func snippetView(w http.ResponseWriter, r *http.Request) {
42+
func (app *application) snippetView(w http.ResponseWriter, r *http.Request) {
4543

4644
id, err := strconv.Atoi(r.URL.Query().Get("id"))
4745

4846
if err != nil || id < 1 {
49-
http.NotFound(w, r)
47+
app.notFound(w)
5048
return
5149
}
5250

5351
fmt.Fprintf(w, "Display a specific snippet with ID %d...", id)
5452
}
5553

5654
// Add a snippetCreate handler function.
57-
func snippetCreate(w http.ResponseWriter, r *http.Request) {
55+
func (app *application) snippetCreate(w http.ResponseWriter, r *http.Request) {
5856

5957
if r.Method != http.MethodPost {
6058
w.Header().Set("Allow", http.MethodPost)
61-
http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed)
59+
app.clientError(w, http.StatusMethodNotAllowed)
6260
return
6361
}
6462

cmd/web/helpers.go

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package main
2+
3+
import (
4+
"net/http"
5+
"runtime/debug"
6+
)
7+
8+
func (app *application) serverError(w http.ResponseWriter, r *http.Request, err error) {
9+
10+
var (
11+
method = r.Method
12+
uri = r.URL.RequestURI()
13+
trace = string(debug.Stack())
14+
)
15+
app.logger.Error(err.Error(), "method", method, "uri", uri, "trace", trace)
16+
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
17+
}
18+
19+
func (app *application) clientError(w http.ResponseWriter, status int) {
20+
http.Error(w, http.StatusText(status), status)
21+
}
22+
23+
func (app *application) notFound(w http.ResponseWriter) {
24+
app.clientError(w, http.StatusNotFound)
25+
}

cmd/web/main.go

+12-12
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@ package main
22

33
import (
44
"flag"
5-
"log"
5+
"log/slog"
66
"net/http"
7+
"os"
78
)
89

910
func main() {
@@ -14,20 +15,19 @@ func main() {
1415
flag.StringVar(&cfg.staticDir, "static-dir", "./ui/static", "Path to static assets")
1516

1617
flag.Parse()
17-
// Register the two new handler functions and corresponding URL patterns with
18-
// the servemux, in exactly the same way that we did before.
19-
mux := http.NewServeMux()
2018

21-
fileServer := http.FileServer(http.Dir(cfg.staticDir))
19+
logger := slog.New(slog.NewJSONHandler(os.Stdout, nil))
2220

23-
mux.Handle("/static/", http.StripPrefix("/static/", fileServer))
21+
// Intialize a new instance of our application struct, containing the
22+
//dependencies
23+
app := &application{
24+
logger: logger,
25+
}
2426

25-
mux.HandleFunc("/", home)
26-
mux.HandleFunc("/snippet/view", snippetView)
27-
mux.HandleFunc("/snippet/create", snippetCreate)
27+
logger.Info("Starting server", slog.String("addr", cfg.addr))
2828

29-
log.Printf("starting server on %s", cfg.addr)
29+
err := http.ListenAndServe(cfg.addr, app.routes())
3030

31-
err := http.ListenAndServe(cfg.addr, mux)
32-
log.Fatal(err)
31+
logger.Error(err.Error())
32+
os.Exit(1)
3333
}

cmd/web/routes.go

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package main
2+
3+
import "net/http"
4+
5+
func (app *application) routes() *http.ServeMux {
6+
7+
var cfg config
8+
9+
mux := http.NewServeMux()
10+
11+
fileServer := http.FileServer(http.Dir(cfg.staticDir))
12+
13+
mux.Handle("/static/", http.StripPrefix("/static/", fileServer))
14+
15+
mux.HandleFunc("/", app.home)
16+
mux.HandleFunc("/snippet/view", app.snippetView)
17+
mux.HandleFunc("/snippet/create", app.snippetCreate)
18+
19+
return mux
20+
}
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
package main
22

3+
import "log/slog"
4+
35
type config struct {
46
addr string
57
staticDir string
68
}
9+
10+
type application struct {
11+
logger *slog.Logger
12+
}

0 commit comments

Comments
 (0)