I am building a Book API in Golang using Gin and GORM. I have successfully implemented the Create, get and delete parts of the API but the Update is resulting in 500 Internal Server Error. I am trying to for a Update functionality which only updates the specific tags provided in the body(example given below). Any help or guidance is greatly appreciated.
GO Logs
[31m2022/05/09 14:08:00 [Recovery] 2022/05/09 - 14:08:00 panic recovered:
PATCH /books/2 HTTP/1.1
Host: 127.0.0.1:8080
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Connection: keep-alive
Content-Length: 66
Content-Type: text/plain;charset=UTF-8
Origin: chrome-extension://ihgpcfpkpmdcghlnaofdmjkoemnlijdi
Sec-Ch-Ua: " Not A;Brand";v="99", "Chromium";v="101", "Google Chrome";v="101"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "Windows"
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: none
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.54 Safari/537.36
reflect: call of reflect.Value.SetString on uint Value
C:/Program Files/Go/src/reflect/value.go:221 (0xc7bb04)
flag.mustBe: panic(&ValueError{methodName(), f.kind()})
C:/Program Files/Go/src/reflect/value.go:1747 (0xc7ba3e)
Value.SetString: v.mustBe(String)
C:/Users/NK086843/go/pkg/mod/gorm.io/[email protected]/schema/field.go:771 (0x10defb7)
(*Field).setupValuerAndSetter.func11: field.ReflectValueOf(ctx, value).SetString(data)
C:/Users/NK086843/go/pkg/mod/gorm.io/[email protected]/callbacks/update.go:144 (0x115b68e)
ConvertToAssignments.func2: field.Set(stmt.Context, stmt.ReflectValue, value)
C:/Users/NK086843/go/pkg/mod/gorm.io/[email protected]/callbacks/update.go:275 (0x11534f9)
ConvertToAssignments: assignValue(field, value)
C:/Users/NK086843/go/pkg/mod/gorm.io/[email protected]/callbacks/update.go:73 (0x115ac9e)
Update.func1: if set := ConvertToAssignments(db.Statement); len(set) != 0 {
C:/Users/NK086843/go/pkg/mod/gorm.io/[email protected]/callbacks.go:130 (0x10ebe14)
(*processor).Execute: f(db)
C:/Users/NK086843/go/pkg/mod/gorm.io/[email protected]/finisher_api.go:372 (0x10f4e8d)
(*DB).Updates: return tx.callbacks.Update().Execute(tx)
C:/New folder/golang/github.com/shashank-kakarla/BookAPI/controllers/books.go:101 (0x1167007)
UpdateBook: models.DB.Model(&book).Updates(input)
C:/Users/NK086843/go/pkg/mod/github.com/gin-gonic/[email protected]/context.go:168 (0x10917e1)
(*Context).Next: c.handlers[c.index](c)
C:/Users/NK086843/go/pkg/mod/github.com/gin-gonic/[email protected]/recovery.go:99 (0x10917c7)
CustomRecoveryWithWriter.func1: c.Next()
C:/Users/NK086843/go/pkg/mod/github.com/gin-gonic/[email protected]/context.go:168 (0x10908c6)
(*Context).Next: c.handlers[c.index](c)
C:/Users/NK086843/go/pkg/mod/github.com/gin-gonic/[email protected]/logger.go:241 (0x1090885)
LoggerWithConfig.func1: c.Next()
C:/Users/NK086843/go/pkg/mod/github.com/gin-gonic/[email protected]/context.go:168 (0x1086689)
(*Context).Next: c.handlers[c.index](c)
C:/Users/NK086843/go/pkg/mod/github.com/gin-gonic/[email protected]/gin.go:555 (0x108666f)
(*Engine).handleHTTPRequest: c.Next()
C:/Users/NK086843/go/pkg/mod/github.com/gin-gonic/[email protected]/gin.go:511 (0x1086112)
(*Engine).ServeHTTP: engine.handleHTTPRequest(c)
C:/Program Files/Go/src/net/http/server.go:2867 (0xe76e29)
serverHandler.ServeHTTP: handler.ServeHTTP(rw, req)
C:/Program Files/Go/src/net/http/server.go:1932 (0xe721ac)
(*conn).serve: serverHandler{c.server}.ServeHTTP(w, w.req)
C:/Program Files/Go/src/runtime/asm_amd64.s:1371 (0xc3d900)
goexit: BYTE $0x90 // NOP
←[0m
[GIN] 2022/05/09 - 14:08:00 |←[97;41m 500 ←[0m| 19.7185ms | 127.0.0.1 |←[97;42m PATCH ←[0m "/books/2"
GO Models
func UpdateBook(c *gin.Context) {
// Get model if exist
var book models.Book
if err := models.DB.Where("id = ?", c.Param("id")).First(&book).Error; err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "Record not found!"})
return
}
// Validate input
var input UpdateBookInput
if err := c.ShouldBindJSON(&input); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
models.DB.Model(&book).Updates(input)
c.JSON(http.StatusOK, gin.H{"data": book})
}
UpdateBookInput Struct
type UpdateBookInput struct {
Title string `json:"title"`
Author string `json:"author"`
}
main.go
func main() {
router := gin.Default()
models.ConnectDatabase()
router.GET("/books", controllers.FetchBooks)
router.GET("/books/:id", controllers.FindBookByID)
router.GET("/books/title/:title", controllers.FindBookByTitle)
router.GET("/books/author/:author", controllers.FindBookByAuthor)
router.POST("/books", controllers.CreateBook)
router.PATCH("/books/:id", controllers.UpdateBook)
router.DELETE("/books/:id", controllers.RemoveBook)
router.Run()
}
Request URL and Body URL
PATCH http://127.0.0.1:8080/books/2
BODY
{
"title": "Breaking Dawn",
}
Schema/Model
package models
type Book struct {
ID uint `json:"id" gorm:"primary_key"`
Title string `json:"title"`
Author string `json:"author"`
}
UpdateBookInput
struct look like?