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 introduced
autoload
)
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 *.