Open1

【Go言語】echo× mysql driverの利用まとめ

eisukeeisuke

必要なものをインポート

go get -u github.com/go-sql-driver/mysql

go get -u ithub.com/labstack/echo/v4

なんも考えずに掛け合わせたテンプレート作成

// デコードする型の作成
type Task struct {
	ID     int    `json:"id"`
	Title  string `json:"title"`
	IsDone bool   `json:"is_done"`
}

func main() {
	e := echo.New()

	db, err := sql.Open("mysql", "user:password@tcp(localhost:3306)/todo")
	if err != nil {
		log.Fatal(err)
	}
	defer db.Close()

	e.GET("/tasks", func(c echo.Context) error {
		tasks := []Task{}
                //SQL文ですでに終了しているものは除外
		rows, err := db.Query("SELECT id, title, is_done FROM tasks WHERE is_done = false")
		if err != nil {
			return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
		}
		defer rows.Close()
                // 返ってきたjsonの数分デコードしてtask配列に入れる
		for rows.Next() {
			var task Task
			if err := rows.Scan(&task.ID, &task.Title, &task.IsDone); err != nil {
				return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
			}
			tasks = append(tasks, task)
		}
                //配列に入ったものをそのままjsonとして返す
		return c.JSON(http.StatusOK, tasks)
	})
        //タスクの追加
	e.POST("/tasks", func(c echo.Context) error {
		task := Task{}
                //タスクをバインドする(デコード)
		if err := c.Bind(&task); err != nil {
			return echo.NewHTTPError(http.StatusBadRequest, err.Error())
		}
                //DBにインサートしていく
		_, err := db.Exec("INSERT INTO tasks(title, is_done) VALUES(?, false)", task.Title)
		if err != nil {
			return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
		}

		return c.NoContent(http.StatusCreated)
	})
        //パラメータからタスクを選択し終了する
	e.DELETE("/tasks/:id", func(c echo.Context) error {
		id, err := strconv.Atoi(c.Param("id"))
		if err != nil {
			return echo.NewHTTPError(http.StatusBadRequest, "Invalid ID format")
		}
                //SQL文で指定したidのタスクを選択して終了状態に変更する
		_, err = db.Exec("UPDATE tasks SET is_done=true WHERE id=?", id)
		if err != nil {
			return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
		}

		return c.NoContent(http.StatusOK)
	})
        //パラメータで指定したタスク情報を取得する
	e.GET("/tasks/:id", func(c echo.Context) error {
		id, err := strconv.Atoi(c.Param("id"))
		if err != nil {
			return echo.NewHTTPError(http.StatusBadRequest, "Invalid ID format")
		}

		var task Task
                //選択したidのタスクを取得する
		err = db.QueryRow("SELECT id, title, is_done FROM tasks WHERE id=?", id).Scan(&task.ID, &task.Title, &task.IsDone)
		if err != nil {
			if err == sql.ErrNoRows {
				return echo.NewHTTPError(http.StatusNotFound, "Task not found")
			}
			return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
		}

		return c.JSON(http.StatusOK, task)
	})

	e.Start(":8080")
}