Learning Golang and Web Development

栏目: IT技术 · 发布时间: 5年前

内容简介:A simple list of concepts and code snippets that would help in learning Golang and applying in Web Development

Learning Golang and Web Development

A simple list of concepts and code snippets that would help in learning Golang and applying in Web Development :tada: . I tried to jot down when I was learning. It might be helpful for beginners who want to learn Go for web development.

:v: Hope you find something useful. If you like it please give it a :star2: .

Contents

Installation

Follow the official doc and setup Go depending on your OS (ie. Windows , Linux, OS X)

Initial Concepts to Study before diving deep

  • Basic Understanding of
    • Variables
    • Constants
    • Packages and import/export
    • Functions
    • Pointers
    • Mutability
  • Types
    • Type Conversion
    • Type assertion**
    • Structs
    • Composition
  • Collection Types
    • Arrays
    • Slicing
    • Range & Maps
  • Control Flow
    • If, For, Switch statement
  • Methods
  • Interfaces
  • Concurrency
    • Goroutines
    • Channels

Basic Hello World

package main

import (
    "fmt"
    "net/http"
)

func main() {
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintf(w, "Hello, World !")
    })

    http.ListenAndServe(":8000", nil)
}

Adding static asset

When we want to serve static files like CSS, JavaScript or images to Web.

func main() {
    http.HandleFunc("/", func (w http.ResponseWriter, r *http.Request) {
        fmt.Fprintf(w, "Hello World!")
    })
   
    fs := http.FileServer(http.Dir("./static"))
    http.Handle("/static/", http.StripPrefix("/static/", fs))

    http.ListenAndServe(":8000", nil)
}

Adding Routes

package main

import (
    "fmt"
    "encoding/json"
    "net/http"
    "github.com/gorilla/mux"
)


type Tasks struct {
    ID 		string  	`json:"id,omitempty"`
    TASKNAME 	string 		`json:"task,omitempty"`
}

var task []Tasks

func getAllTask(w http.ResponseWriter, r *http.Request) {
	json.NewEncoder(w).Encode(task)
}


func getTask(w http.ResponseWriter, r *http.Request) {
	params := mux.Vars(r)
	for _,item := range task {
		if item.ID == params["id"] {
			json.NewEncoder(w).Encode(item)
			return
		}
	}
	json.NewEncoder(w).Encode(&Tasks{})
}


func main() {
	router := mux.NewRouter()
	router.HandleFunc("/task", getAllTask).Methods("GET")
	router.HandleFunc("/task/{id}", getTask).Methods("GET")
	
	http.ListenAndServe(":8000", router)
}

Adding Forms

Considering the form has 2 fields Email and Message .

package main

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

type Details struct {
    Email   string
    Message string
}

func messageHandle(w http.ResponseWriter, r *http.Request) {
	if err := r.ParseForm(); err != nil {
		fmt.Fprintf(w, "ParseForm() err: %v", err)
		return
	}
	
	data := Details{
		Email:   r.FormValue("email"),
		Message: r.FormValue("message"),
        }

        // do something with the data
}

func main() {
    http.HandleFunc("/", messageHandle)
    
    if err := http.ListenAndServe(":8080", nil); err != nil {
        log.Fatal(err)
    }
}

Adding MiddleWare

Here, the Middleware function allows adding more than one layer of middleware and handle them appropriately. SomeMiddleware is the middleware function which gets called before the route handler function getAllTask

package main

import (
    "encoding/json"
    "log"
    "net/http"
    "github.com/gorilla/mux"
)

func getAllTask(w http.ResponseWriter, r *http.Request) {
	// ... do something inside this route
}


// Function allows adding more than one layer of middleware and handle them appropriately

func Middleware(h http.Handler, middleware ...func(http.Handler) http.Handler) http.Handler {
    for _, mw := range middleware {
        h = mw(h)
    }
    return h
}

// Middlware function

func SomeMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		
		 // ... do middleware things

        next.ServeHTTP(w, r)
    })
}

func main() {

	router := mux.NewRouter()
	router.Handle("/task", Middleware(
        http.HandlerFunc(getAllTask),
        SomeMiddleware,
    ))
    log.Fatal(http.ListenAndServe(":8000", router))
}

Sessions Management

import (
    "os"
    "log"
    "net/http"
    "github.com/gorilla/sessions"
)

var store = sessions.NewCookieStore([]byte(os.Getenv("SESSION_KEY")))

func Handlerfunction(w http.ResponseWriter, r *http.Request) {
	session, err := store.Get(r, "session-name")
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	
	// Set some session values.
    	session.Values["hello"] = "world"
    	// Save it 
    	session.Save(r, w)
}


func main() {
    http.HandleFunc("/", Handlerfunction)
    
    if err := http.ListenAndServe(":8080", nil); err != nil {
        log.Fatal(err)
    }
}

Adding Database

Here in this example we have connected MongoDB with our application and saved sample data into the collection

package main

import (
"context"
"fmt"
"os"
"time"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)

type Data struct {
	ID  int `json:"Field Int"`
	Task string `json:"Field Str"`
}

func main() {
	
	clientOptions := options.Client().ApplyURI("<MONGO_URI>") 

	// Connect to the MongoDB
	client, err := mongo.Connect(context.TODO(), clientOptions)
	
	if err != nil {
		fmt.Println("mongo.Connect() ERROR:", err)
		os.Exit(1)
	}

	// To manage multiple API requests
	ctx, _ := context.WithTimeout(context.Background(), 15*time.Second)

	// Access a MongoDB collection through a database
	col := client.Database("DATABASE_NAME").Collection("COLLECTION_NAME")

	// Declare a MongoDB struct instance for the document's fields and data
	newData := Data{
		ID: 12,
		Task: "Learn Go",
	}

	result, err := col.InsertOne(ctx, newData)
	if err != nil {
		fmt.Println("ERROR:", err)
		os.Exit(1)

	} else {
	fmt.Println("Result:", result)
	}
}

Writing Unit Test

Consider thesection for testing. The below test case is for the /task route which returns an array of tasks created by users.

package main

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

func TestGetAllTask(t *testing.T) {
	req, err := http.NewRequest("GET", "http://localhost:8000/task", nil)
	if err != nil {
		t.Fatal(err)
	}
	res := httptest.NewRecorder()
	handler := http.HandlerFunc(getAllTask)
	handler.ServeHTTP(res, req)
	
	if status := res.Code; status != http.StatusOK {
		t.Errorf("Wrong Status Code: got %v want %v",
			status, http.StatusOK)
	}

	// Check the response body is what we expect.
	expected := `[{"id":"1","task":"Hello"},{"id":"2","task":"World"},{"id":"3","task":"yeah"}]`

	if strings.TrimRight(res.Body.String(),"\n") != expected {
		t.Errorf("ERROR: got %v want %v",
			res.Body.String(), expected)
	}
}

Remember Test file should be name of original file + test like: base.go - base_test.go .(good practice)

After running the above test case by go test -v command, the following output will appear

F:\Go\src\Rest_API>go test -v
=== RUN   TestGetAllTask
--- PASS: TestGetAllTask (0.00s)
PASS
ok      Rest_API        0.454s

Licence

MIT © Debasish Sahoo


以上所述就是小编给大家介绍的《Learning Golang and Web Development》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

理解专业程序员

理解专业程序员

(美)杰拉尔德·温伯格(GeraldM.Weinberg) / 刘天北 / 清华大学出版社 / 2006-7 / 25.00元

《理解专业程序员》通过行内专家的独特视角,介绍了如何成为优秀程序员,如何提高工作绩效等问题。全书由多篇讨论程序员职业的短文组成,内容精彩绝伦,是一部任何在这个变化急剧的领域工作的人都不可错过的重要作品。本书论述生动翔实——你肯定能从中认出你自己和你的公司的故事——因此不仅极富教益,而且读来也引人入胜。 各篇主题包括:对于专业程序员重要的若干问题,成为专业程序员的途径,在企业官僚体......一起来看看 《理解专业程序员》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

URL 编码/解码
URL 编码/解码

URL 编码/解码

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具