Last active
April 18, 2022 19:27
-
-
Save chilledoj/359241fdb37ef7cb7dee45898cfbec3a to your computer and use it in GitHub Desktop.
Go Std Library HTTP Code Snippets
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| {{define "base"}} | |
| <!DOCTYPE html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="utf-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1"> | |
| <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.1/css/bulma.min.css"> | |
| <link href='https://cdn.jsdelivr.net/npm/css.gg/icons/all.css' rel='stylesheet'> | |
| <title>{{defTitle .Title}}</title> | |
| </head> | |
| <body> | |
| <div class="container is-fullhd"> | |
| <nav class="navbar pl-4" role="navigation" aria-label="main navigation"> | |
| <div class="navbar-brand"> | |
| <a class="navbar-item" href="/">SimpleTask</a> | |
| </div> | |
| </nav> | |
| {{template "content" .}} | |
| </div> | |
| </body> | |
| </html> | |
| {{end}} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package main | |
| import ( | |
| "flag" | |
| "log" | |
| "net" | |
| ) | |
| func main() { | |
| var ( | |
| host = flag.String("host", "", "host http address to listen on") | |
| port = flag.String("port", "8000", "port number for http listener") | |
| ) | |
| flag.Parse() | |
| addr := net.JoinHostPort(*host, *port) | |
| if err := runHttp(addr); err != nil { | |
| log.Fatal(err) | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package main | |
| import ( | |
| "fmt" | |
| "net/http" | |
| ) | |
| func runHttp(listenAddr string) error { | |
| s := http.Server{ | |
| Addr: listenAddr, | |
| Handler: http.DefaultServeMux, | |
| } | |
| fmt.Printf("Starting HTTP listener at %s\n", listenAddr) | |
| return s.ListenAndServe() | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* router/errors.go */ | |
| type httpErr struct { | |
| err error | |
| msg string | |
| } | |
| func (he httpErr) Error() string { | |
| return he.err.Error() | |
| } | |
| func ErrJSON(w http.ResponseWriter, err error, code int) { | |
| v, ok := err.(httpErr) | |
| if !ok { | |
| fmt.Printf("An error occurred: %v", err) | |
| http.Error(w, err.Error(), code) | |
| return | |
| } | |
| fmt.Printf("An error occurred: %v", v.err) | |
| JSON(w, map[string]string{ | |
| "error": v.msg, | |
| }, code) | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| func extractTaskId(r *http.Request) (string, error) { | |
| if len(r.URL.Path) < 2 { | |
| return "", fmt.Errorf("no task id provided") | |
| } | |
| // We know our subrouter will only provide the id as the root path item. | |
| return strings.Split(r.URL.Path[1:], "/")[0], nil | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| {{define "content"}} | |
| <div class="container"> | |
| <section class="hero is-info is-bold"> | |
| <div class="hero-body"> | |
| <div class="container"> | |
| <h1 class="title">Tasks</h1> | |
| </div> | |
| </div> | |
| </section> | |
| <div class="block is-flex is-justify-content-flex-end p-4"> | |
| <a href="/new" class="button is-primary" > | |
| <span class="icon"> | |
| <i class="gg-add"></i> | |
| </span> | |
| <span>Add</span> | |
| </a> | |
| </div> | |
| <div class="block" id="tasks"> | |
| <div class="columns is-multiline"> | |
| {{range $i , $task := .Tasks}} | |
| <div class="column is-one-third"> | |
| <div class="card"> | |
| <div class="card-content"> | |
| <p class="title">{{$task.title}}</p> | |
| <p>{{$task.details}}</p> | |
| </div> | |
| <footer class="card-footer"> | |
| <a href="/edit/{{$task.id}}" class="card-footer-item">Edit</a> | |
| <a href="/delete/{{$task.id}}" class="card-footer-item">Delete</a> | |
| </footer> | |
| </div> | |
| </div> | |
| {{end}} | |
| </div> | |
| </div> | |
| </div> | |
| {{end}} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* router/json.go */ | |
| func JSON(w http.ResponseWriter, data interface{}, code int) { | |
| buf, err := json.Marshal(data) | |
| if err != nil { | |
| http.Error(w, err.Error(), http.StatusInternalServerError) | |
| return | |
| } | |
| w.Header().Set("Content-Type", "application/json") | |
| status := http.StatusOK | |
| if code != 0 { | |
| status = code | |
| } | |
| w.WriteHeader(status) | |
| w.Write(buf) | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| .PHONY: build | |
| build: | |
| go build -o ./bin/mystdhttp ./cmd/. | |
| .PHONY: run | |
| run: build | |
| ./bin/mystdhttp |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| func logMiddleware(handler http.Handler) http.Handler { | |
| return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | |
| // Pre-work | |
| nw := time.Now() | |
| // Run Handler | |
| handler.ServeHTTP(w, r) | |
| // Post-work | |
| fmt.Printf("%s %s %s %s\n", r.RemoteAddr, r.Method, r.URL, time.Since(nw)) | |
| }) | |
| } | |
| func recoverMiddleware(handler http.Handler) http.Handler { | |
| return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | |
| defer func() { | |
| if err := recover(); err != nil { | |
| fmt.Printf("RECOVERING: %v\n", err) | |
| http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) | |
| } | |
| }() | |
| handler.ServeHTTP(w, r) | |
| }) | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| func NewRouter() http.Handler { | |
| mux := http.NewServeMux() | |
| mux.HandleFunc("/", taskListPage()) | |
| return mux | |
| } | |
| var tasks = []map[string]string{ | |
| {"id": "task-01", "title": "test", "details": "a test task", "status": "active"}, | |
| {"id": "task-02", "title": "Another Test", "details": "# Title\n\n+ Some Stuff to do\n+ Another item\n\nSomething else written here", "status": "active"}, | |
| {"id": "task-03", "title": "Test 3", "details": "a test task 3", "status": "active"}, | |
| {"id": "task-04", "title": "Test 4", "details": "a test task 4", "status": "active"}, | |
| {"id": "task-05", "title": "Test 5", "details": "a test task 5", "status": "active"}, | |
| {"id": "task-06", "title": "Test 6", "details": "a test task 6", "status": "pending"}, | |
| {"id": "task-07", "title": "Test 7", "details": "a test task 7", "status": "pending"}, | |
| {"id": "task-08", "title": "Test 8", "details": "a test task 8", "status": "active"}, | |
| {"id": "task-09", "title": "Test 9", "details": "a test task 9", "status": "inactive"}, | |
| {"id": "task-10", "title": "Test 10", "details": "a test task 10", "status": "inactive"}, | |
| } | |
| func taskListPage() http.HandlerFunc { | |
| files := tmplLayout("./web/templates/index.gohtml") | |
| tmpl := template.Must(template.New("index").Funcs(defaultFuncs).ParseFiles(files...)) | |
| return func(w http.ResponseWriter, r *http.Request) { | |
| if r.URL.Path != "/" || r.Method != http.MethodGet { | |
| http.NotFound(w, r) | |
| return | |
| } | |
| var buf bytes.Buffer | |
| if err := tmpl.ExecuteTemplate(&buf, "base", map[string]interface{}{ | |
| "Tasks": tasks, | |
| }); err != nil { | |
| fmt.Printf("ERR: %v\n", err) | |
| http.Error(w, err.Error(), http.StatusInternalServerError) | |
| return | |
| } | |
| w.WriteHeader(http.StatusOK) | |
| io.Copy(w, &buf) | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* web/templates/_notFound.gohtml */ | |
| {{define "content"}} | |
| <div class="container"> | |
| <section class="hero is-medium is-warning is-bold"> | |
| <div class="hero-body"> | |
| <div class="container"> | |
| <h1 class="title"> | |
| Not Found | |
| </h1> | |
| <h2 class="subtitle"> | |
| Sorry...we couldn't find that one. | |
| </h2> | |
| </div> | |
| </div> | |
| </section> | |
| <div class="block p-2"> | |
| <a href="/" class="button is-info is-outlined"> | |
| <span class="icon"> | |
| <i class="gg-home"></i> | |
| </span> | |
| <span>Home<span> | |
| </a> | |
| </div> | |
| </div> | |
| {{end}} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| func (th *TasksHandler) readTaskHandler(w http.ResponseWriter, r *http.Request) { | |
| taskId, err:= extractTaskId(r) | |
| if err!=nil{ | |
| ErrJSON(w, httpErr{err: err, msg: "not found"}, http.StatusNotFound) | |
| return | |
| } | |
| task ,err:= someDB.GetTaskById(taskId) | |
| ... | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| type TasksHandler struct {} | |
| func (th *TasksHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { | |
| switch r.Method { | |
| case http.MethodGet: | |
| if r.URL.Path == "/" { | |
| th.listTaskHandler(w, r) | |
| return | |
| } | |
| th.readTaskHandler(w, r) | |
| case http.MethodPost: | |
| th.createTaskHandler(w, r) | |
| case http.MethodPut: | |
| th.updateTaskHandler(w, r) | |
| case http.MethodDelete: | |
| th.deleteTaskHandler(w, r) | |
| default: | |
| msg := http.StatusText(http.StatusNotFound) | |
| ErrJSON(w, httpErr{err: fmt.Errorf(msg), msg: msg }, http.StatusNotFound) | |
| } | |
| } | |
| func (th *TasksHandler) listTaskHandler(w http.ResponseWriter, r *http.Request) { | |
| // TODO: List Tasks | |
| } | |
| func (th *TasksHandler) readTaskHandler(w http.ResponseWriter, r *http.Request) { | |
| // TODO: Read Task by ID | |
| } | |
| func (th *TasksHandler) deleteTaskHandler(w http.ResponseWriter, r *http.Request) { | |
| // TODO: Delete Task by ID | |
| } | |
| func (th *TasksHandler) createTaskHandler(w http.ResponseWriter, r *http.Request) { | |
| // TODO: Create Task by ID | |
| } | |
| func (th *TasksHandler) updateTaskHandler(w http.ResponseWriter, r *http.Request) { | |
| // TODO: Update Task by ID | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* routes/router.go */ | |
| // Change the http.NotFound to notFoundPage(w, r) | |
| func taskListPage() http.HandlerFunc { | |
| ... | |
| return func(w http.ResponseWriter, r *http.Request) { | |
| if r.URL.Path != "/" || r.Method != http.MethodGet { | |
| notFoundPage(w, r) | |
| return | |
| } | |
| ... | |
| } | |
| } | |
| ... at the end of the file add this function | |
| var notFoundPage = func() http.HandlerFunc { | |
| files := tmplLayout("./web/templates/_notFound.gohtml") | |
| tmpl := template.Must(template.New("index").Funcs(defaultFuncs).ParseFiles(files...)) | |
| return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | |
| var buf bytes.Buffer | |
| if err := tmpl.ExecuteTemplate(&buf, "base", nil); err != nil { | |
| fmt.Printf("ERR: %v\n", err) | |
| http.Error(w, err.Error(), http.StatusInternalServerError) | |
| return | |
| } | |
| w.WriteHeader(http.StatusOK) | |
| io.Copy(w, &buf) | |
| }) | |
| }() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package router | |
| import "net/http" | |
| func NewRouter() http.Handler { | |
| mux := http.NewServeMux() | |
| mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { | |
| w.WriteHeader(http.StatusOK) | |
| w.Write([]byte("ok")) | |
| }) | |
| return mux | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package router | |
| import "html/template" | |
| var defaultFuncs = template.FuncMap{ | |
| "defTitle": func(ip interface{}) string { | |
| v, ok := ip.(string) | |
| if !ok || (ok && v == "") { | |
| return "Tasks - Golang Std HTTP" | |
| } | |
| return v | |
| }, | |
| } | |
| var templateFiles = []string{ | |
| "./web/templates/base.gohtml", | |
| } | |
| func tmplLayout(files ...string) []string { | |
| return append(templateFiles, files...) | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment