To develop a Golang REST API that interacts with a MySQL database to perform CRUD operations on a "tasks" table, follow these steps:

1. Install required packages
2. Set up the database connection and create the tasks table
3. Create data structures for Task and Response
4. Implement functions for CRUD operations
5. Set up routes and handlers for the API

Let's go through each step in detail.

### 1. Install required packages

First, you need to install the following packages if you haven't already:

- Gorilla Mux for routing: `go get -u github.com/gorilla/mux`
- Go MySQL Driver: `go get -u github.com/go-sql-driver/mysql`

### 2. Set up the database connection and create the tasks table

Create a new file called `main.go` and add the following code to set up the database connection:

```go
package main

import (
	"database/sql"
	"fmt"
	"log"

	_ "github.com/go-sql-driver/mysql"
)

var db *sql.DB

func initDB() {
	var err error
	dataSourceName := "username:password@tcp(localhost:3306)/dbname?parseTime=true"
	db, err = sql.Open("mysql", dataSourceName)
	if err != nil {
		log.Fatal(err)
	}

	err = db.Ping()
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("Database connection established")
}

func main() {
	initDB()
	defer db.Close()

	// TODO: Add API routes and handlers here
}
```

Replace `username`, `password`, and `dbname` with your actual MySQL credentials and database name.

Now, create the `tasks` table in your MySQL database using this SQL query:

```sql
CREATE TABLE tasks (
    id INT AUTO_INCREMENT PRIMARY KEY,
    title VARCHAR(255) NOT NULL,
    description TEXT,
    due_date DATE
);
```

### 3. Create data structures for Task and Response

Add the following code to `main.go` to define the `Task` and `Response` structs:

```go
type Task struct {
	ID          int    `json:"id"`
	Title       string `json:"title"`
	Description string `json:"description"`
	DueDate     string `json:"due_date"` // Use string type for easier JSON marshaling/unmarshaling
}

type Response struct {
	Message string `json:"message"`
}
```

### 4. Implement functions for CRUD operations

Now, implement the functions for creating, reading, updating, and deleting tasks in the database. Add the following code to `main.go`:

```go
func createTask(task *Task) error {
	stmt, err := db.Prepare("INSERT INTO tasks(title, description, due_date) VALUES(?, ?, ?)")
	if err != nil {
		return err
	}
	defer stmt.Close()

	result, err := stmt.Exec(task.Title, task.Description, task.DueDate)
	if err != nil {
		return err
	}

	id, err := result.LastInsertId()
	if err != nil {
		return err
	}
	task.ID = int(id)

	return nil
}

func getTasks() ([]Task, error) {
	rows, err := db.Query("SELECT id, title, description, due_date FROM tasks")
	if err != nil {
		return nil, err
	}
	defer rows.Close()

	var tasks []Task
	for rows.Next() {
		var task Task
		err := rows.Scan(&task.ID, &task.Title, &task.Description, &task.DueDate)
		if err != nil {
			return nil, err
		}
		tasks = append(tasks, task)
	}

	return tasks, nil
}

func getTask(id int) (*Task, error) {
	row := db.QueryRow("SELECT id, title, description, due_date FROM tasks WHERE id=?", id)

	var task Task
	err := row.Scan(&task.ID, &task.Title, &task.Description, &task.DueDate)
	if err != nil {
		return nil, err
	}

	return &task, nil
}

func updateTask(task *Task) error {
	stmt, err := db.Prepare("UPDATE tasks SET title=?, description=?, due_date=? WHERE id=?")
	if err != nil {
		return err
	}
	defer stmt.Close()

	_, err = stmt.Exec(task.Title, task.Description, task.DueDate, task.ID)
	return err
}

func deleteTask(id int) error {
	stmt, err := db.Prepare("DELETE FROM tasks WHERE id=?")
	if err != nil {
		return err
	}
	defer stmt.Close()

	_, err = stmt.Exec(id)
	return err
}
```

### 5. Set up routes and handlers for the API

Finally, set up the routes and handlers for the REST API using Gorilla Mux. Add the following code to `main.go`:

```go
import (
	"encoding/json"
	"net/http"
	"strconv"

	"github.com/gorilla/mux"
)

func main() {
	initDB()
	defer db.Close()

	router := mux.NewRouter()
	router.HandleFunc("/tasks", createTaskHandler).Methods("POST")
	router.HandleFunc("/tasks", getTasksHandler).Methods("GET")
	router.HandleFunc("/tasks/{id}", getTaskHandler).Methods("GET")
	router.HandleFunc("/tasks/{id}", updateTaskHandler).Methods("PUT")
	router.HandleFunc("/tasks/{id}", deleteTaskHandler).Methods("DELETE")

	log.Fatal(http.ListenAndServe(":8080", router))
}

func createTaskHandler(w http.ResponseWriter, r *http.Request) {
	var task Task
	err := json.NewDecoder(r.Body).Decode(&task)
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	err = createTask(&task)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(task)
}

func getTasksHandler(w http.ResponseWriter, r *http.Request) {
	tasks, err := getTasks()
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(tasks)
}

func getTaskHandler(w http.ResponseWriter, r *http.Request) {
	id, err := strconv.Atoi(mux.Vars(r)["id"])
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	task, err := getTask(id)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(task)
}

func updateTaskHandler(w http.ResponseWriter, r *http.Request) {
	var task Task
	err := json.NewDecoder(r.Body).Decode(&task)
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	id, err := strconv.Atoi(mux.Vars(r)["id"])
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}
	task.ID = id

	err = updateTask(&task)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(Response{Message: "Task updated successfully"})
}

func deleteTaskHandler(w http.ResponseWriter, r *http.Request) {
	id, err := strconv.Atoi(mux.Vars(r)["id"])
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	err = deleteTask(id)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(Response{Message: "Task deleted successfully"})
}
```

Now you can run the API with `go run main.go` and test it using a tool like Postman or curl.
MySQL 데이터베이스와 상호 작용하여 "tasks" 테이블에서 CRUD 작업을 수행하는 Golang REST API를 개발하려면 다음 단계를 따르세요.

1. 필요한 패키지를 설치합니다
2. 데이터베이스 연결을 설정하고 작업 테이블을 생성합니다
3. 작업 및 응답을 위한 데이터 구조 생성
4. CRUD 작업을 위한 함수 구현
5. API를 위한 경로 및 핸들러 설정

각 단계를 자세히 살펴보겠습니다.

### 1. 필요한 패키지 설치

먼저, 아직 설치하지 않은 패키지가 있다면 다음 패키지를 설치해야 합니다.

- 라우팅을 위한 Gorilla Mux: `go get -u github.com/gorilla/mux`
- Go MySQL 드라이버: `go get -u github.com/go-sql-driver/mysql`

### 2. 데이터베이스 연결 설정 및 작업 테이블 생성

`main.go`라는 새 파일을 생성하고 다음 코드를 추가하여 데이터베이스 연결을 설정합니다:

```go
package main

import (
	"database/sql"
	"fmt"
	"log"

	_ "github.com/go-sql-driver/mysql"
)

var db *sql.DB

func initDB() {
	var err error
	dataSourceName := "username:password@tcp(localhost:3306)/dbname?parseTime=true"
	db, err = sql.Open("mysql", dataSourceName)
	if err != nil {
		log.Fatal(err)
	}

	err = db.Ping()
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("Database connection established")
}

func main() {
	initDB()
	defer db.Close()

	// TODO: Add API routes and handlers here
}
```

`username`, `password`, `dbname`을 실제 MySQL 자격 증명 및 데이터베이스 이름으로 바꿉니다.

다음, 이 SQL 쿼리를 사용하여 MySQL 데이터베이스에 `tasks` 테이블을 생성합니다:

```sql
CREATE TABLE tasks (
    id INT AUTO_INCREMENT PRIMARY KEY,
    title VARCHAR(255) NOT NULL,
    description TEXT,
    due_date DATE
);
```

### 3. 태스크 및 응답에 대한 데이터 구조 생성

다음 코드를 `main.go`에 추가하여 `Task` 및 `Response` 구조를 정의합니다:

```go
type Task struct {
	ID          int    `json:"id"`
	Title       string `json:"title"`
	Description string `json:"description"`
	DueDate     string `json:"due_date"` // Use string type for easier JSON marshaling/unmarshaling
}

type Response struct {
	Message string `json:"message"`
}
```

### 4. CRUD 작업을 위한 함수 구현

이제 데이터베이스에서 작업을 생성, 읽기, 업데이트 및 삭제하는 함수를 구현합니다. `main.go`에 다음 코드를 추가합니다:

```go
func createTask(task *Task) error {
	stmt, err := db.Prepare("INSERT INTO tasks(title, description, due_date) VALUES(?, ?, ?)")
	if err != nil {
		return err
	}
	defer stmt.Close()

	result, err := stmt.Exec(task.Title, task.Description, task.DueDate)
	if err != nil {
		return err
	}

	id, err := result.LastInsertId()
	if err != nil {
		return err
	}
	task.ID = int(id)

	return nil
}

func getTasks() ([]Task, error) {
	rows, err := db.Query("SELECT id, title, description, due_date FROM tasks")
	if err != nil {
		return nil, err
	}
	defer rows.Close()

	var tasks []Task
	for rows.Next() {
		var task Task
		err := rows.Scan(&task.ID, &task.Title, &task.Description, &task.DueDate)
		if err != nil {
			return nil, err
		}
		tasks = append(tasks, task)
	}

	return tasks, nil
}

func getTask(id int) (*Task, error) {
	row := db.QueryRow("SELECT id, title, description, due_date FROM tasks WHERE id=?", id)

	var task Task
	err := row.Scan(&task.ID, &task.Title, &task.Description, &task.DueDate)
	if err != nil {
		return nil, err
	}

	return &task, nil
}

func updateTask(task *Task) error {
	stmt, err := db.Prepare("UPDATE tasks SET title=?, description=?, due_date=? WHERE id=?")
	if err != nil {
		return err
	}
	defer stmt.Close()

	_, err = stmt.Exec(task.Title, task.Description, task.DueDate, task.ID)
	return err
}

func deleteTask(id int) error {
	stmt, err := db.Prepare("DELETE FROM tasks WHERE id=?")
	if err != nil {
		return err
	}
	defer stmt.Close()

	_, err = stmt.Exec(id)
	return err
}
```

### 5. API에 대한 경로 및 핸들러 설정

마지막으로, Gorilla Mux를 사용하여 REST API에 대한 경로와 핸들러를 설정합니다. `main.go`에 다음 코드를 추가합니다:

```go
import (
	"encoding/json"
	"net/http"
	"strconv"

	"github.com/gorilla/mux"
)

func main() {
	initDB()
	defer db.Close()

	router := mux.NewRouter()
	router.HandleFunc("/tasks", createTaskHandler).Methods("POST")
	router.HandleFunc("/tasks", getTasksHandler).Methods("GET")
	router.HandleFunc("/tasks/{id}", getTaskHandler).Methods("GET")
	router.HandleFunc("/tasks/{id}", updateTaskHandler).Methods("PUT")
	router.HandleFunc("/tasks/{id}", deleteTaskHandler).Methods("DELETE")

	log.Fatal(http.ListenAndServe(":8080", router))
}

func createTaskHandler(w http.ResponseWriter, r *http.Request) {
	var task Task
	err := json.NewDecoder(r.Body).Decode(&task)
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	err = createTask(&task)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(task)
}

func getTasksHandler(w http.ResponseWriter, r *http.Request) {
	tasks, err := getTasks()
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(tasks)
}

func getTaskHandler(w http.ResponseWriter, r *http.Request) {
	id, err := strconv.Atoi(mux.Vars(r)["id"])
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	task, err := getTask(id)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(task)
}

func updateTaskHandler(w http.ResponseWriter, r *http.Request) {
	var task Task
	err := json.NewDecoder(r.Body).Decode(&task)
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	id, err := strconv.Atoi(mux.Vars(r)["id"])
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}
	task.ID = id

	err = updateTask(&task)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(Response{Message: "Task updated successfully"})
}

func deleteTaskHandler(w http.ResponseWriter, r *http.Request) {
	id, err := strconv.Atoi(mux.Vars(r)["id"])
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	err = deleteTask(id)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(Response{Message: "Task deleted successfully"})
}
```

이제 `go run main.go`로 API를 실행하고 Postman이나 curl과 같은 도구를 사용하여 테스트할 수 있습니다.