FROM golang:alpine
WORKDIR /main
RUN apk add --no-cache curl git
COPY go.mod go.sum ./
RUN go mod download
COPY main.go .
RUN go build -o main main.go
EXPOSE 8080
CMD ["./main"]
Docker
복사
package main
import (
"database/sql"
"encoding/json"
"fmt"
"log"
"net/http"
"os"
"strconv"
_ "github.com/go-sql-driver/mysql"
"github.com/gorilla/mux"
)
type User struct {
ID int `json:"id"`
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
Email string `json:"email"`
}
type App struct {
DB *sql.DB
}
func main() {
dbUser := os.Getenv("DB_USER")
dbPassword := os.Getenv("DB_PASSWORD")
dbHost := os.Getenv("DB_HOST")
dbPort := os.Getenv("DB_PORT")
dbName := os.Getenv("DB_NAME")
dsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&parseTime=True&loc=Local",
dbUser, dbPassword, dbHost, dbPort, dbName)
db, err := sql.Open("mysql", dsn)
if err != nil {
log.Fatal("Failed to connect to database:", err)
}
defer db.Close()
err = db.Ping()
if err != nil {
log.Fatal("Failed to ping database:", err)
}
fmt.Println("Successfully connected to database")
app := App{DB: db}
router := mux.NewRouter()
router.HandleFunc("/users", app.createUser).Methods("POST")
router.HandleFunc("/users/{id}", app.getUser).Methods("GET")
router.HandleFunc("/users/{id}", app.updateUser).Methods("PUT")
router.HandleFunc("/users/{id}", app.deleteUser).Methods("DELETE")
log.Println("Server starting on :8080")
log.Fatal(http.ListenAndServe(":8080", router))
}
// Create
func (app *App) createUser(w http.ResponseWriter, r *http.Request) {
var user User
if err := json.NewDecoder(r.Body).Decode(&user); err != nil {
http.Error(w, "Invalid request body", http.StatusBadRequest)
return
}
query := "INSERT INTO users (first_name, last_name, email) VALUES (?, ?, ?)"
result, err := app.DB.Exec(query, user.FirstName, user.LastName, user.Email)
if err != nil {
http.Error(w, fmt.Sprintf("Error creating user: %v", err), http.StatusInternalServerError)
return
}
id, _ := result.LastInsertId()
user.ID = int(id)
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusCreated)
json.NewEncoder(w).Encode(user)
}
// Read
func (app *App) getUser(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
id, err := strconv.Atoi(vars["id"])
if err != nil {
http.Error(w, "Invalid user ID", http.StatusBadRequest)
return
}
var user User
query := "SELECT id, first_name, last_name, email FROM users WHERE id = ?"
err = app.DB.QueryRow(query, id).Scan(&user.ID, &user.FirstName, &user.LastName, &user.Email)
if err == sql.ErrNoRows {
http.Error(w, "User not found", http.StatusNotFound)
return
} else if err != nil {
http.Error(w, fmt.Sprintf("Error fetching user: %v", err), http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(user)
}
// Update
func (app *App) updateUser(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
id, err := strconv.Atoi(vars["id"])
if err != nil {
http.Error(w, "Invalid user ID", http.StatusBadRequest)
return
}
var user User
if err := json.NewDecoder(r.Body).Decode(&user); err != nil {
http.Error(w, "Invalid request body", http.StatusBadRequest)
return
}
user.ID = id
query := "UPDATE users SET first_name = ?, last_name = ?, email = ? WHERE id = ?"
result, err := app.DB.Exec(query, user.FirstName, user.LastName, user.Email, user.ID)
if err != nil {
http.Error(w, fmt.Sprintf("Error updating user: %v", err), http.StatusInternalServerError)
return
}
rowsAffected, _ := result.RowsAffected()
if rowsAffected == 0 {
http.Error(w, "User not found", http.StatusNotFound)
return
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(user)
}
// Delete
func (app *App) deleteUser(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
id, err := strconv.Atoi(vars["id"])
if err != nil {
http.Error(w, "Invalid user ID", http.StatusBadRequest)
return
}
query := "DELETE FROM users WHERE id = ?"
result, err := app.DB.Exec(query, id)
if err != nil {
http.Error(w, fmt.Sprintf("Error deleting user: %v", err), http.StatusInternalServerError)
return
}
rowsAffected, _ := result.RowsAffected()
if rowsAffected == 0 {
http.Error(w, "User not found", http.StatusNotFound)
return
}
w.WriteHeader(http.StatusNoContent)
}
Go
복사
