当前位置:网站首页>Go language library management restful API development practice
Go language library management restful API development practice
2022-06-25 06:26:00 【InfoQ】
1. preparation
- browser
- gorilla/handlers
- gorilla/mux
2. Application structure
├── main.go
└── src
├── app.go
├── data.go
├── handlers.go
├── helpers.go
└── middlewares.go
Go Toolkits and modules
srcgo mod init bookstore
go.mod3. structure API
main.gopackage main
import"bookstore/src"
func main() {
src.Start()
}
package mainsrcbookstoremain()srcStart()main.goRoutes and handlers
Muxapp.gopackage src
import (
"github.com/gorilla/handlers"
"github.com/gorilla/mux"
"log"
"net/http"
"os"
)
func Start() {
router := mux.NewRouter()
router.Use(commonMiddleware)
router.HandleFunc("/book", getAllBooks).Methods(http.MethodGet)
router.HandleFunc("/book", addBook).Methods(http.MethodPost)
router.HandleFunc("/book/{book_id:[0-9]+}", getBook).Methods(http.MethodGet)
router.HandleFunc("/book/{book_id:[0-9]+}", updateBook).Methods(http.MethodPut)
router.HandleFunc("/book/{book_id:[0-9]+}", deleteBook).Methods(http.MethodDelete)
log.Fatal(http.ListenAndServe("localhost:5000", handlers.LoggingHandler(os.Stdout, router)))
}
app.gomain.goStart()muxhandlersgo get github.com/gorilla/handlers
go get github.com/gorilla/mux
go.modmodule bookstore
go1.17
require (
github.com/gorilla/handlers v1.5.1
github.com/gorilla/mux v1.8.0
)
require github.com/felixge/httpsnoop v1.0.1// indirect
Start()MuxMuxrouter.Use(commonMiddleware)
router.HandleFunc("/book/{book_id:[0-9]+}", updateBook).Methods(http.MethodPut)
/book/123PUTupdateBookbook_idmiddleware
Content-Typeapp.goStart()router.Use(commonMiddleware)
middlewares.gopackage src
import"net/http"
func commonMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("content-type", "application/json; charset=utf-8")
w.Header().Set("x-content-type-options", "nosniff")
next.ServeHTTP(w, r)
})
}
Start()commonMiddlewareStatic data
srcdata.gopackage src
type Book struct {
Id int`json:"id"`
Title string`json:"title"`
Author string`json:"author"`
Genre string`json:"genre"`
}
var booksDB = []Book{
{Id: 123, Title: "The Hobbit", Author: "J. R. R. Tolkien", Genre: "Fantasy"},
{Id: 456, Title: "Harry Potter and the Philosopher's Stone", Author: "J. K. Rowling", Genre: "Fantasy"},
{Id: 789, Title: "The Little Prince", Author: "Antoine de Saint-Exupéry", Genre: "Novella"},
}
type CustomResponse struct {
Code int `json:"code"`
Message string `json:"message"`
Description string `json:"description,omitempty"`
}
var responseCodes = map[int]string {
400: "Bad Request",
401: "Unauthorized",
403: "Forbidden",
404: "Not Found",
409: "Conflict",
422: "Validation Error",
429: "Too Many Requests",
500: "Internal Server Error",
}
Auxiliary tool
helpers.gopackage src
import (
"encoding/json"
"net/http"
)
func removeBook(s []Book, i int) []Book {
if i != len(s)-1 {
s[i] = s[len(s)-1]
}
return s[:len(s)-1]
}
func checkDuplicateBookId(s []Book, id int) bool {
for _, book := range s {
if book.Id == id {
return true
}
}
return false
}
func JSONResponse(w http.ResponseWriter, code int, desc string) {
w.WriteHeader(code)
message, ok := responseCodes[code]
if !ok {
message = "Undefined"
}
r := CustomResponse{
Code: code,
Message: message,
Description: desc,
}
_ = json.NewEncoder(w).Encode(r)
}
removeBookBookcheckDuplicateBookIdBookJSONResponseCustomResponseresponseCodesThe handler
handlers.gopackage src
import (
"encoding/json"
"github.com/gorilla/mux"
"net/http"
"strconv"
)
Get a single book
func getBook(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
bookId, _ := strconv.Atoi(vars["book_id"])
for _, book := range booksDB {
if book.Id == bookId {
_ = json.NewEncoder(w).Encode(book)
return
}
}
JSONResponse(w, http.StatusNotFound, "")
}
404: Not FoundGet all the books
func getAllBooks(w http.ResponseWriter, r *http.Request) {
_ = json.NewEncoder(w).Encode(booksDB)
}
Add a new book
func addBook(w http.ResponseWriter, r *http.Request) {
decoder := json.NewDecoder(r.Body)
var b Book
err := decoder.Decode(&b)
if err != nil {
JSONResponse(w, http.StatusBadRequest, "")
return
}
if checkDuplicateBookId(booksDB, b.Id) {
JSONResponse(w, http.StatusConflict, "")
return
}
booksDB = append(booksDB, b)
w.WriteHeader(201)
_ = json.NewEncoder(w).Encode(b)
}
{
"id": 999,
"title": "SomeTitle",
"author": "SomeAuthor",
"genre": "SomeGenre"
}
400: Bad Request error409: Conflict error backUpdate existing books
func updateBook(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
bookId, _ := strconv.Atoi(vars["book_id"])
decoder := json.NewDecoder(r.Body)
var b Book
err := decoder.Decode(&b)
if err != nil {
JSONResponse(w, http.StatusBadRequest, "")
return
}
for i, book := range booksDB {
if book.Id == bookId {
booksDB[i] = b
_ = json.NewEncoder(w).Encode(b)
return
}
}
JSONResponse(w, http.StatusNotFound, "")
}
404: Not FoundDelete existing books
func deleteBook(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
bookId, _ := strconv.Atoi(vars["book_id"])
for i, book := range booksDB {
if book.Id == bookId {
booksDB = removeBook(booksDB, i)
_ = json.NewEncoder(w).Encode(book)
return
}
}
JSONResponse(w, http.StatusNotFound, "")
}
removeBook404: Not Found4. Run and test API
go run main.go
边栏推荐
- At the age of 26, I was transferred to software testing with zero foundation. Now I have successfully entered the job with a monthly salary of 12K. However, no one understands my bitterness
- Understanding the dynamic mode of mongodb document
- Asemi fast recovery diode us1m parameters, us1m recovery time, us1m voltage drop
- Tail command – view the contents at the end of the file
- 50 days countdown! Are you ready for the Landbridge cup provincial tournament?
- @Principle of preauthorize permission control
- China rehabilitation hospital industry operation benefit analysis and operation situation investigation report 2022
- With a younger brother OCR, say no to various types of verification codes!
- [data visualization application] draw spatial map (with R language code)
- Uni app wechat applet customer service chat function
猜你喜欢

Digitalization, transformation?

What elements are indispensable for the development of the character? What are the stages

Mongodb basic concept learning - set

3-7sql injection website instance step 3: attack type and attack strategy

Tencent and China Mobile continued to buy back with large sums of money, and the leading Hong Kong stocks "led" the market to rebound?

Es11 new methods: dynamic import(), bigint, globalthis, optional chain, and null value merging operator

DNS domain name system

What is the slice flag bit

IQ debugging of Hisilicon platform ISP and image (1)

Location object
随机推荐
MV command – move or rename files
[speech discrimination] discrimination of speech signals based on MATLAB double threshold method [including Matlab source code 1720]
What is the slice flag bit
CTFSHOW
Brief introduction and use of JSON
ARM processor operating mode
Personal blog system graduation project opening report
General test point ideas are summarized and shared, which can be directly used in interview and actual software testing
【LeetCode】40. Combined summation II (2 strokes of wrong questions)
No one reads the series. Source code analysis of copyonwritearraylist
[road of system analyst] collection of wrong questions in the chapters of Applied Mathematics and economic management
Advantages and disadvantages of using SNMP and WMI polling
Wechat applet authorization login + mobile phone sending verification code +jwt verification interface (laravel8+php)
@The difference between notempty, @notnull and @notblank
@Principle of preauthorize permission control
The elephant turns around and starts the whole body. Ali pushes Maoxiang not only to Jingdong
Echo command – output a string or extract the value of a shell variable
How to use asemi FET 7n80 and how to use 7n80
Go uses channel to control concurrency
DF command – displays disk space usage