質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Echo(フレームワーク)

Echoは、Go言語で作られたフレームワーク。非常に軽量で、小~中規模のアプリ構成を想定した仕様になっています。公式ドキュメントが用意されており、初心者でも始めやすい点が特徴です。

Go

Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

Q&A

2回答

5056閲覧

【Go】echoでのUpdate実装で500エラーが返り実行できない

kioak

総合スコア20

Echo(フレームワーク)

Echoは、Go言語で作られたフレームワーク。非常に軽量で、小~中規模のアプリ構成を想定した仕様になっています。公式ドキュメントが用意されており、初心者でも始めやすい点が特徴です。

Go

Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

0グッド

0クリップ

投稿2019/07/24 15:00

編集2019/07/30 18:14

前提・実現したいこと

echoでのユーザー情報をUpdateする関数の実装

http://localhost:8888/api/v1/users/:id にてPUTでユーザーを更新しようとしています
{"name" : "なまえ"} という様なjsonを送ってとりあえず処理を実行したいと思ってます.

使用ツール

  • echo
  • gorm

発生している問題・エラーメッセージ

ルーティング・(送信している)JSON・dbのコネクションなどは,他のCRAETE・READ・DELETEが同じような処理で動いているのため問題ないと思います.

500: Internal Server Error

該当のソースコード

go

1func UpdateUser() echo.HandlerFunc { 2 return func(c echo.Context) (err error) { 3 db, err := gorm.Open("mysql", "mysql設定") 4 CheckConnectError(err) //エラーハンドリングの関数 5 defer db.Close() 6 7 user := new(model.User) 8 if err := c.Bind(user); err != nil { 9 return err 10 } 11 id, _ := strconv.Atoi(c.Param("id")) 12 model.Users[id].Name = user.Name 13 return c.JSON(http.StatusOK, "ok") 14 } 15}

model.Users[id].Nameは,modelパッケージのUsers変数をidで取ってきてNameに代入がしたくて書いています.
公式のドキュメントを参考にしました.

## model/user.go ~略 var ( Users = map[int]*User{} Seq = 1 ) 略~

https://echo.labstack.com/cookbook/crud

処理がおかしいところはありますでしょうか.
よろしくお願いします

追記

ログはこのようになっております.

log

1time:2019-07-26T15:37:53+09:00 host:::1 2forwardedfor: req:- 3status:500 4method:PUT 5uri:/api/v1/users/3 6size:36 referer: 7ua:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36 8reqtime_ns:1895431 9cache:- runtime:- 10apptime:- 11vhost:localhost:8888 12reqtime_human:1.895431ms 13x-request-id: host:localhost:8888

下記はかなり見辛いログですが,載せておきます.

log

1{"time":"2019-07-26T15:37:53.480874+09:00","level":"-","prefix":"echo","file":"recover.go","line":"73","message":"[PANIC RECOVER] runtime error: invalid memory address or nil pointer dereference goroutine 50 [running]:\necho/middleware.RecoverWithConfig.func1.1.1(0x156b148, 0x1000, 0xc000060000, 0x160b140, 0xc0002b2120)\n\t/Users/kirohi/go/src/echo/middleware/recover.go:71 +0xf1\npanic(0x14cc0e0, 0x195b440)\n\t/usr/local/Cellar/go/1.12.5/libexec/src/runtime/panic.go:522 +0x1b5\ngithub.com/ia17011/subsc/backend/api.UpdateUser.func1(0x160b140, 0xc0002b2120, 0x0, 0x0)\n\t/Users/kirohi/go/src/github.com/ia17011/subsc/backend/api/user.go:74 +0x19d\ngithub.com/labstack/echo.(*Echo).add.func1(0x160b140, 0xc0002b2120, 0xc0002160a0, 0xf)\n\t/Users/kirohi/go/src/github.com/labstack/echo/echo.go:505 +0x87\ngithub.com/ia17011/subsc/backend/api/middlewares.serverHeader.func1(0x160b140, 0xc0002b2120, 0x156b148, 0x1000)\n\t/Users/kirohi/go/src/github.com/ia17011/subsc/backend/api/middlewares/mainMiddlewares.go:25 +0x235\necho/middleware.RecoverWithConfig.func1.1(0x160b140, 0xc0002b2120, 0x0, 0x0)\n\t/Users/kirohi/go/src/echo/middleware/recover.go:78 +0xd5\necho/middleware.LoggerWithConfig.func2.1(0x160b140, 0xc0002b2120, 0x3, 0x4)\n\t/Users/kirohi/go/src/echo/middleware/logger.go:119 +0x1c0\ngithub.com/labstack/echo.(*Echo).ServeHTTP(0xc00028a000, 0x15fe860, 0xc0002bc000, 0xc0001e8a00)\n\t/Users/kirohi/go/src/github.com/labstack/echo/echo.go:616 +0x22d\nnet/http.serverHandler.ServeHTTP(0xc000226750, 0x15fe860, 0xc0002bc000, 0xc0001e8a00)\n\t/usr/local/Cellar/go/1.12.5/libexec/src/net/http/server.go:2774 +0xa8\nnet/http.(*conn).serve(0xc00021e0a0, 0x15ff560, 0xc0001ecc00)\n\t/usr/local/Cellar/go/1.12.5/libexec/src/net/http/server.go:1878 +0x851\ncreated by net/http.(*Server).Serve\n\t/usr/local/Cellar/go/1.12.5/libexec/src/net/http/server.go:2884 +0x2f4\n\ngoroutine 1 [IO wait]:\ninternal/poll.runtime_pollWait(0x1e91ea8, 0x72, 0x0)\n\t/usr/local/Cellar/go/1.12.5/libexec/src/runtime/netpoll.go:182 +0x56\ninternal/poll.(*pollDesc).wait(0xc000232818, 0x72, 0x0, 0x0, 0x154be4a)\n\t/usr/local/Cellar/go/1.12.5/libexec/src/internal/poll/fd_poll_runtime.go:87 +0x9b\ninternal/poll.(*pollDesc).waitRead(...)\n\t/usr/local/Cellar/go/1.12.5/libexec/src/internal/poll/fd_poll_runtime.go:92\ninternal/poll.(*FD).Accept(0xc000232800, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)\n\t/usr/local/Cellar/go/1.12.5/libexec/src/internal/poll/fd_unix.go:384 +0x1ba\nnet.(*netFD).accept(0xc000232800, 0x30, 0x50, 0x50)\n\t/usr/local/Cellar/go/1.12.5/libexec/src/net/fd_unix.go:238 +0x42\nnet.(*TCPListener).accept(0xc0002222f8, 0xc0f05880cb, 0xc000088000, 0xc00010dd00)\n\t/usr/local/Cellar/go/1.12.5/libexec/src/net/tcpsock_posix.go:139 +0x32\nnet.(*TCPListener).AcceptTCP(0xc0002222f8, 0x100000001, 0xc00010dd30, 0x104c368)\n\t/usr/local/Cellar/go/1.12.5/libexec/src/net/tcpsock.go:247 +0x48\ngithub.com/labstack/echo.tcpKeepAliveListener.Accept(0xc0002222f8, 0xc00010dd58, 0x10afda6, 0x5d3a9fc1, 0x1036bcf)\n\t/Users/kirohi/go/src/github.com/labstack/echo/echo.go:820 +0x2f\nnet/http.(*Server).Serve(0xc000226750, 0x15fe4e0, 0xc000222300, 0x0, 0x0)\n\t/usr/local/Cellar/go/1.12.5/libexec/src/net/http/server.go:2859 +0x22d\ngithub.com/labstack/echo.(*Echo).StartServer(0xc00028a000, 0xc000226750, 0x0, 0x0)\n\t/Users/kirohi/go/src/github.com/labstack/echo/echo.go:707 +0x388\ngithub.com/labstack/echo.(*Echo).Start(...)\n\t/Users/kirohi/go/src/github.com/labstack/echo/echo.go:627\nmain.main()\n\t/Users/kirohi/go/src/github.com/ia17011/subsc/backend/main.go:16 +0x67\n\ngoroutine 51 [runnable]:\ndatabase/sql.(*DB).connectionOpener(0xc0002ca000, 0x15ff560, 0xc000220300)\n\t/usr/local/Cellar/go/1.12.5/libexec/src/database/sql/sql.go:1000 +0xe8\ncreated by database/sql.OpenDB\n\t/usr/local/Cellar/go/1.12.5/libexec/src/database/sql/sql.go:670 +0x15e\n\ngoroutine 35 [runnable]:\ngithub.com/go-sql-driver/mysql.(*mysqlConn).startWatcher.func1(0xc0001f9080, 0xc0002c6120, 0xc0001f62a0)\n\t/Users/kirohi/go/src/github.com/go-sql-driver/mysql/connection.go:619 +0xbf\ncreated by github.com/go-sql-driver/mysql.(*mysqlConn).startWatcher\n\t/Users/kirohi/go/src/github.com/go-sql-driver/mysql/connection.go:616 +0xbe\n\ngoroutine 52 [runnable]:\ndatabase/sql.(*DB).connectionResetter(0xc0002ca000, 0x15ff560, 0xc000220300)\n\t/usr/local/Cellar/go/1.12.5/libexec/src/database/sql/sql.go:1013 +0x\n"}

api/user.goと送信しているjsonの追記

go

1package api 2 3import ( 4 "fmt" 5 "net/http" 6 "strconv" 7 8 "github.com/ia17011/subsc/backend/model" 9 "github.com/jinzhu/gorm" 10 "github.com/labstack/echo" 11 uuid "github.com/satori/go.uuid" 12) 13 14func getUUID() string { 15 u, err := uuid.NewV4() 16 if err != nil { 17 fmt.Printf("Something went wrong: %s", err) 18 } 19 uu := u.String() 20 return uu 21} 22 23func CreateUser() echo.HandlerFunc { 24 return func(c echo.Context) (err error) { 25 db, err := gorm.Open("mysql", "kirohi:cSbuS2mlGo##@/subsc?charset=utf8&parseTime=True&loc=Local") 26 CheckConnectError(err) 27 defer db.Close() 28 user := &model.User{ 29 Id: model.Seq, 30 } 31 if err := c.Bind(&user); err != nil { 32 return err 33 } 34 35 model.Users[user.Id] = user 36 model.Seq++ 37 db.Create(&user) 38 return c.JSON(http.StatusOK, user) 39 } 40} 41func FindUserById() echo.HandlerFunc { 42 return func(c echo.Context) (err error) { 43 db, err := gorm.Open("mysql", "kirohi:cSbuS2mlGo##@/subsc?charset=utf8&parseTime=True&loc=Local") 44 CheckConnectError(err) 45 defer db.Close() 46 user := model.User{} 47 48 id := c.Param("id") 49 db.First(&user, id) 50 51 return c.JSON(http.StatusOK, user) 52 } 53} 54 55func UpdateUser() echo.HandlerFunc { 56 return func(c echo.Context) (err error) { 57 db, err := gorm.Open("mysql", "kirohi:cSbuS2mlGo##@/subsc?charset=utf8&parseTime=True&loc=Local") 58 CheckConnectError(err) 59 defer db.Close() 60 61 user := model.User{} 62 if err = c.Bind(user); err != nil { 63 return 64 } 65 id, _ := strconv.Atoi(c.Param("id")) 66 db.Where("Id=?", id).Find(&user) 67 68 user.Name = c.Param("name") 69 70 fmt.Println(user.Name) 71 // //model.Users[id].Name = "あああ" 72 // //fmt.Println(model.Users[id]) 73 // return c.JSON(http.StatusOK, user) 74 return c.JSON(http.StatusOK, "ok") 75 } 76} 77 78func DeleteUser() echo.HandlerFunc { 79 return func(c echo.Context) (err error) { 80 db, err := gorm.Open("mysql", "kirohi:cSbuS2mlGo##@/subsc?charset=utf8&parseTime=True&loc=Local") 81 CheckConnectError(err) 82 defer db.Close() 83 user := model.User{} 84 85 name := c.Param("name") 86 87 db.Where("name=?", name).Find(&user) 88 db.Delete(&user) 89 90 return c.NoContent(http.StatusOK) 91 } 92} 93 94func NewUser(user *model.User) { 95 db, err := gorm.Open("mysql", "kirohi:cSbuS2mlGo##@/subsc?charset=utf8&parseTime=True&loc=Local") 96 CheckConnectError(err) 97 defer db.Close() 98 db.Create(user) 99} 100 101func FindUser(u *model.User) *model.User { 102 db, err := gorm.Open("mysql", "kirohi:cSbuS2mlGo##@/subsc?charset=utf8&parseTime=True&loc=Local") 103 CheckConnectError(err) 104 defer db.Close() 105 106 user := model.User{} 107 db.Where(u).First(&user) 108 return &user 109} 110

json
http://localhost:8888/api/v1/users/3 というurlに対して,{ "name" : "あああ" } というbodyをContent-Type application/json,POSTで投げています.
ここでidが3であるユーザーの存在は,FindByUserID(),すなわちGETリクエストで確認できています.

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nobonobo

2019/07/25 04:57

サーバーサイド側のログになにか出ていますでしょうか?そちらがあれば何が問題なのか予想しやすいです。
kioak

2019/07/26 06:41

質問へ追記致しました.よろしくお願いいたします
teikoku-penguin

2019/07/26 11:19

送っているjsonとapi/user.goも記載して下さい
guest

回答2

0

api/user.goのL74

go

1 model.Users[id].Name = user.Name

とする時点ではmodel.Users[id]が存在しないように見えます
なので null pointer になっているのだと思います

再現
https://play.golang.org/p/4rNcjUEmsdb

投稿2019/07/26 21:36

teikoku-penguin

総合スコア314

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kioak

2019/07/30 18:13

ご回答ありがとうございます.ご指摘通り,nullになっていました.このmapを作って処理するのはechoの公式のCRUDのレシピを参考にしたのですが,他のいい方法があれば教えていただけるとうれしいです
teikoku-penguin

2019/07/30 18:23

usersMap := make(map[int]User{}) など書き方は色々あると思いますが、ユーザー情報をPOST or PATCHでクライアントから受けてDBの内容を更新する処理では使わなくていいかなと思います どちらかと言えば、DBから複数のユーザーを取得した時になにかしらの処理をする場合に扱いやすくするなどで使うかなと思います
guest

0

return c.JSON(http.StatusOK, "ok")

としている所ですが、
jsonにできるstructではなくではなく文字列をわたしてしまってますね?

"ok" のかわりに model.Users[id] を指定してみてはいかがでしょうか

投稿2019/07/25 15:51

calkinos

総合スコア452

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kioak

2019/07/26 06:42

ご回答ありがとうございます.何度か試してみましたが,500エラーから変化無しでした.
calkinos

2019/07/26 23:54

UpdateでもDBからデータを持ってこないとダメですね。 DBアクセス関連コードがコメントアウトされているようですが、何か理由があったのでしょうか。
kioak

2019/07/30 18:11

DBアクセス関連コードは何度か色々試してみて上手くいかなかったため置いていました.
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問