package main
import "fmt"
func main() {
fmt.Println("Hello Gopher!")
}
go build hellogopher.go // 1. Compile code
./hellogopher // 2. Run binary
go run hellogopher.go // Compile code + run binary
// Variable
var kitty string = "Kitty"
bella := "Bella"
// Array (fixed length)
namesArray := [3]string{kitty, bella, "Cleo"}
// Slice (variable length)
namesSlice := make([]string, 2)
namesSlice[0] = kitty
// Loop
for i, name := range namesSlice {
fmt.Println("Hello " + name + "!")
}
type Cat struct {
Name string
}
func main() {
c := Cat{Name: "Kitty"}
fmt.Println("Hello " + c.Name + "!")
}
// Error as return value
func (c Cat) feed(food string) error {
if c.Name == "Kitty" && food != "Steak Tartare" {
return errors.New("Won't eat!")
}
return nil
}
func main() {
c := Cat{Name: "Kitty"}
// Handle error
err := c.feed("Caviar")
if err != nil {
fmt.Printf("%v won't eat it.", c.Name)
}
}
# Create directory
mkdir cats
cd cats
# Enable dependency tracking
go mod init goday.com/cats
# Create go file
touch main.go
func catAPIHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Meow!")
w.WriteHeader(http.StatusOK)
}
func main() {
http.HandleFunc("/api/cats", catAPIHandler)
http.ListenAndServe(":8080", nil)
}
type Cat struct {
Name string
}
func catAPIHandler(w http.ResponseWriter, r *http.Request) {
cats := make([]Cat, 1)
cats[0] = Cat{Name: "Ginger"}
json.NewEncoder(w).Encode(c)
}
func main() {
http.HandleFunc("/api/cats", catAPIHandler)
http.ListenAndServe(":8080", nil)
}
# Query cat API
curl -s http://localhost:8080/api/cats | jq
[
{
"Name": "Ginger"
}
]
type Cat struct {
Name string `json:"name"`
}
func catAPIHandler(w http.ResponseWriter, r *http.Request) {
cats := make([]Cat, 1)
cats[0] = Cat{Name: "Ginger"}
json.NewEncoder(w).Encode(cats)
}
func main() {
http.HandleFunc("/api/cats", catAPIHandler)
http.ListenAndServe(":8080", nil)
}
cat_api_test.go
func TestCatAPIHandler(t *testing.T) {
// 1. Create test request
req, _ := http.NewRequest("GET", "/api/cats", nil)
// 2. Create recorder (which satisfies http.ResponseWriter)
recorder := httptest.NewRecorder()
// 3. Invoke handler
catAPIHandler(recorder, req)
// 4. Check the response
if recorder.Code != http.StatusOK {
t.Errorf("Wrong status: got %v expected %v", recorder.Code, http.StatusOK)
}
}
# Run tests
go test -v ./...
=== RUN TestCatAPIHandler
--- PASS: TestCatAPIHandler (0.00s)
PASS
coverage: 50.0% of statements
ok devopscon.com/cats 0.127s coverage: 50.0% of statements
Makefile
.DEFAULT_GOAL := build
BIN_FILE=cats
build:
go build -o dist/"${BIN_FILE}"
test:
go test -v ./...
run:
./"${BIN_FILE}"
clean:
go clean
func indexHandler(w http.ResponseWriter, r *http.Request) {
var tpl = template.Must(template.ParseFiles("index.html"))
tpl.Execute(w, nil)
}
func main() {
http.HandleFunc("/", indexHandler)
http.ListenAndServe(":8080", nil)
}
func indexHandler(w http.ResponseWriter, r *http.Request) {
var tpl = template.Must(template.ParseFiles("index.html"))
tpl.Execute(w, nil)
}
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/", indexHandler)
http.ListenAndServe(":8080", mux)
}
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/", indexHandler)
// Serve files
fs := http.FileServer(http.Dir("assets"))
mux.Handle("/assets/", http.StripPrefix("/assets/", fs))
http.ListenAndServe(":8080", mux)
}
//go:embed assets
var assets embed.FS
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/", indexHandler)
// Serve files
mux.Handle("/assets/", http.FileServer(http.FS(assets)))
http.ListenAndServe(":8080", mux)
}
main.go
type Cat struct {
Name string
}
func indexHandler(w ResponseWriter, r *Request) {
// Create cat slice
cat := make([]Cat, 1)
// Add cat ginger
cat[0] = Cat{Name: "Ginger"}
// Render template
tpl.Execute(w, cat)
}
index.html
<body>
<h1>Cats App</h1>
{{ range. }}
<h2>{{ .Name }}</h2>
{{ end }}
</body>
GET https://api.thecatapi.com/v1/breeds?limit=5
[
{
"id": "abys",
"name": "Abyssinian",
"image": {
"url": "https://cdn2.thecatapi.com/images/0XYvRd7oD.jpg"
}
},
{
"id": "aege",
"name": "Aegean",
"image": {
"url": "https://cdn2.thecatapi.com/images/ozEvzdVM-.jpg"
}
},
...
]
type Cat struct {
ID string `json:"id"`
Name string `json:"name"`
Image struct {
URL string `json:"url"`
} `json:"image"`
}
func indexHandler(w http.ResponseWriter, r *http.Request) {
resp, err := http.Get("https://api.thecatapi.com/v1/breeds?limit=5")
if err != nil {
http.Error(w, "Cats API error", http.StatusInternalServerError)
return
}
// Create cat slice
cat := make([]Cat, 5)
// Read and parse body
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
json.Unmarshal(body, &cat)
tpl.Execute(w, cat)
}
http.Handler
func loggingMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
log.Printf("%v requested URL %v", r.Host, r.URL)
next.ServeHTTP(w, r)
})
}
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/", indexHandler)
http.ListenAndServe(":8080", loggingMiddleware(mux))
}