如何使用post方法更新已经存储的值

问题描述

例如, 我使用 post 方法创建这样的新记录

ID: "1",Isbn: "438227",Title: "Book One",Author: &Author{Firstname: "John",Lastname: "Doe"}}

我需要相同的 post 方法来更新这样的数据

ID: "1",Isbn: "5000656",Title: "Book One new",Author: &Author{Firstname: "Johndoe",Lastname: "D"}}
package main

import (
    "encoding/json"
    "log"
    "math/rand"
    "net/http"
    "strconv"

    "github.com/gorilla/mux"
)

// Book struct (Model)
type Book struct {
    ID     string  `json:"id"`
    Isbn   string  `json:"isbn"`
    Title  string  `json:"title"`
    Author *Author `json:"author"`
}

// Author struct
type Author struct {
    Firstname string `json:"firstname"`
    Lastname  string `json:"lastname"`
}

// Init books var as a slice Book struct
var books []Book

// Get all books
func getBooks(w http.ResponseWriter,r *http.Request) {
    w.Header().Set("Content-Type","application/json")
    json.NewEncoder(w).Encode(books)
}

// Get single book
func getBook(w http.ResponseWriter,"application/json")
    params := mux.Vars(r) // Gets params
    // Loop through books and find one with the id from the params
    for _,item := range books {
        if item.ID == params["id"] {
            json.NewEncoder(w).Encode(item)
            return
        }
    }
    json.NewEncoder(w).Encode(&Book{})
}

// Add new book
func createBook(w http.ResponseWriter,"application/json")
    var book Book
    _ = json.NewDecoder(r.Body).Decode(&book)
    book.ID = strconv.Itoa(rand.Intn(100000000)) // Mock ID - not safe
    books = append(books,book)
    json.NewEncoder(w).Encode(book)
}

// Delete book
func deleteBook(w http.ResponseWriter,"application/json")
    params := mux.Vars(r)
    for index,item := range books {
        if item.ID == params["id"] {
            books = append(books[:index],books[index+1:]...)
            break
        }
    }
    json.NewEncoder(w).Encode(books)
}

// Main function
func main() {
    // Init router
    r := mux.NewRouter()

    // Hardcoded data - @todo: add database
    books = append(books,Book{ID: "1",Lastname: "Doe"}})
    books = append(books,Book{ID: "2",Isbn: "454555",Title: "Book Two",Author: &Author{Firstname: "Steve",Lastname: "Smith"}})

    // Route handles & endpoints
    r.HandleFunc("/books",getBooks).Methods("GET")
    r.HandleFunc("/books/{id}",getBook).Methods("GET")
    r.HandleFunc("/books",createBook).Methods("POST")
    r.HandleFunc("/books/{id}",deleteBook).Methods("DELETE")

    // Start server
    log.Fatal(http.ListenAndServe(":8000",r))
}

如何解决这个问题?

解决方法

有多种设计方法。

一个简单的方法:

  1. 添加另一个处理程序 updateBook,它从 POST 数据中获取 ID 和更新信息
  2. updateBook 挂接到某个路径上的 POST 方法,例如 /books/{id} 上的 POST

在您现有的代码中,您拥有完成这些任务所需的所有示例:您已经连接了多个路径,并且您拥有从 POST 正文中获取数据的 createBook 处理程序。

如果同一个 POST 可以创建或更新记录,那会很奇怪,但我想你也可以这样做。例如:如果您的 POST 数据有 ID,您可以更新现有记录;否则你创建一个新的。