Please start with 0

Before implementing the dynamic API, let’s implement a simple static page rendering

package main

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

func homePage(w http.ResponseWriter, r *http.Request)  {
	fmt.Fprint(w, "HomePage")
	fmt.Println("Loading HomePage is complete.")}func handleRequests(a)  {
	http.HandleFunc("/", homePage)
	log.Fatal(http.ListenAndServe(": 8080".nil))}func main(a) {
	handleRequests()
}
Copy the code

The homePage function is responsible for rendering the static page, and the handleRequests function is responsible for routing all requests to the URL root path to homePage.

This routing

In practice, the same service will contain multiple apis to respond to different functions, so the routing module must be used. Here we use gorilla/ Mux, a third party package, for routing.

func handleRequests(a)  {
	myRouter := mux.NewRouter()

	myRouter.HandleFunc("/", homePage)
	/ / list
	myRouter.HandleFunc("/all", listAdx)
	/ / details
	myRouter.HandleFunc("/adx/{id}", detailAdx).Methods("GET")
	/ / new
	myRouter.HandleFunc("/adx", createAdx).Methods("POST")
	/ / edit
	myRouter.HandleFunc("/adx/{id}", updateAdx).Methods("POST")
	/ / delete
	myRouter.HandleFunc("/adx/{id}", deleteAdx). Methods("DELETE")

	log.Fatal(http.ListenAndServe(": 8080", myRouter))
}
Copy the code

The parameters of the route are resolved

Usually in some function-specific API, parameters are routed (the detailed API in the example above), and we first need to parse the parameters from the API. Gorilla/Mux provides us with a method to resolve the routing mode pass parameters

vars := mux.Vars(r)
id := vars["id"]
Copy the code

C. the ORM

The most common third-party package for Golang to interact with the database is Go-SQL-Driver, but here we use another third-party package, GorM. Gorm can be used much like ORM in PHP, both to run native SQL statements and to make chained calls.

  • Defining a structure
package main

type Adx struct {
	Id		int		`json:"id,omitempty"`
	Name	string	`json:"name,omitempty"`
}
Copy the code
  • Initialize the database connection (the database connection information is configured in the.env file. Dotenv is used here to read the configuration information, so it needs to be introducedautoload)
package main

import (
	"fmt"
	_ "github.com/joho/godotenv/autoload"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"log"
	"os"
)

var (
	host		string
	port		string
	dbName		string
	username	string
	password	string
	timeout		string
	DB			*gorm.DB
)

func init(a){
	host := os.Getenv("HOST")
	port := os.Getenv("PORT")
	dbName := os.Getenv("DATABASE")
	username := os.Getenv("USERNAME")
	password := os.Getenv("PASSWORD")
	timeout := os.Getenv("TIMEOUT")

	dsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s? timeout=%s&charset=utf8mb4&parseTime=True&loc=Local", username, password, host, port, dbName, timeout)

	fmt.Println(dsn)

	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})

	iferr ! =nil {
		log.Fatal(err.Error())
	}

	DB = db
}
Copy the code
  • Perform the CURD operation on the data
package main

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

func listAdx(w http.ResponseWriter, r *http.Request) {
	var records []Adx

	DB.Table("adx").
		Scan(&records)

	json.NewEncoder(w).Encode(records)
}

func detailAdx(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	id := vars["id"]

	var adx Adx
	DB.Table("adx").
		Where("id = ?", id).
		First(&adx)

	json.NewEncoder(w).Encode(adx)
}

func createAdx(w http.ResponseWriter, r *http.Request) {
	var adxs []Adx
	request, _ := ioutil.ReadAll(r.Body)
	json.Unmarshal(request, &adxs)

	fmt.Printf("%+v\n", adxs)

	DB.Table("adx").
		Create(&adxs)

	json.NewEncoder(w).Encode(adxs)
}

func updateAdx(w http.ResponseWriter, r *http.Request) {
	var adx Adx
	vars := mux.Vars(r)
	id, _ := strconv.Atoi(vars["id"])
	fmt.Printf("id = %d\n", id)

	request,_ := ioutil.ReadAll(r.Body)
	json.Unmarshal(request, &adx)
	fmt.Printf("%+v\n", adx)

	DB.Table("adx").
		Where("id = ?", id).
		Updates(adx)

	ifDB.Error ! =nil {
		json.NewEncoder(w).Encode(DB.Error)
	} else {
		adx.Id = id
		json.NewEncoder(w).Encode(adx)
	}
}

func deleteAdx(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	id, _ := strconv.Atoi(vars["id"])
	// Check whether the record exists
	var count int64
	DB.Table("adx").
		Where("id = ?", id).
		Count(&count)

	if count == 0 {
		json.NewEncoder(w).Encode("The record does not exist.")
		return
	}

	DB.Table("adx").
		Delete(&Adx{}, id)

	ifDB.Error ! =nil {
		json.NewEncoder(w).Encode(DB.Error)
	} else {
		json.NewEncoder(w).Encode("Operation successful")}}Copy the code

In the above code, route passes are resolved using gorilla/ Mux package methods, but POST passes are resolved using Ioutil and JSON.

_____ the API across domains

In the context of the separation of the front and back ends of web applications, the back-end API is required to support cross-domain. To implement cross-domain in the GO apis, you still need to rely on third-party packages, using github.com/rs/cors here.

package main

import (
	"github.com/gorilla/mux"
	"github.com/rs/cors"
	"log"
	"net/http"
)

func handleRequests(a)  {
	myRouter := mux.NewRouter()

	myRouter.HandleFunc("/", homePage)
	/ / list
	myRouter.HandleFunc("/all", listAdx)
	/ / details
	myRouter.HandleFunc("/adx/{id}", detailAdx).Methods("GET")
	/ / new
	myRouter.HandleFunc("/adx", createAdx).Methods("POST")
	/ / edit
	myRouter.HandleFunc("/adx/{id}", updateAdx).Methods("POST")
	/ / delete
	myRouter.HandleFunc("/adx/{id}", deleteAdx). Methods("DELETE")
        
        c := cors.New(cors.Options{
		AllowedOrigins: []string{"*"},
	})

	handler := c.Handler(myRouter)

	log.Fatal(http.ListenAndServe(": 8080", handler))
}
Copy the code

In practice, AllowedOrigins is usually set to the actual domain name for security reasons, but this is just a DEMO, so it’s *.