go gin multipart 画像保存

公式通りに進めていけばそんなに難しくなかったけど、忘れないうちにアウトプット

今回はreactでaxios使用してサーバー側に送りました。 商品を名前や詳細と同時に画像を保存する処理です。(validationとかはまだ) ginにはSaveUploadFileという関数が用意されています。引数にそのファイルとディレクトリを指定あげればapp内に保存されます。

ItemController

func Store(c *gin.Context) {
    var item domain.Item
    err := c.Bind(&item)
        if err != nil {
            c.String(http.StatusBadRequest, "Request is failed: "+err.Error())
        return
    }
        //商品画像とリレーション紐づけるのでidの返り値を貰う。
    id := repository.SaveItem(&item)

        //同じファイル名が重複しないようにランダム値に変更
    file, _ := c.FormFile("image")
    fileName := filepath.Ext(file.Filename)
        newFileName := uuid.New().String() + fileName
    filePath := "./public/images/"

  //ここはいらないかも
    if f, exist := os.Stat(filePath); os.IsNotExist(exist) || 
    !f.IsDir() {
        c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{
                    "message": "error. could not find dir",
                })
        }

        //ここでディレクトリに保存、公式参照
    er := c.SaveUploadedFile(file, filePath + newFileName)
    if er != nil {
        c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{
                "message": "Unable to save the file",
        })
        return
  }
  
    //ファイル情報をDBに保存
    repository.SaveItemImage(newFileName, id)

    c.JSON(http.StatusCreated, gin.H{
        "name": item.Name,
        "detail": item.Detail,
        })
}

ItemImageRepository

//ここは結構シンプルです
func SaveItemImage(fileName string, id uint) {
    fmt.Println()
        filePath := "/public/images/"
    db := database.GormConnect()

    var data domain.ItemImage

    data.ItemId = id
    data.File_name = fileName
    data.Path = filePath + fileName

    now := time.Now()
        data.CreatedAt = now
        data.UpdatedAt = now  
    db.Create(&data)
}

とりあえず動くことは動きます。 まだまだこれで運用には程遠いと思いますので、この後は例外処理とか入れてハンドリング予定