Created
May 13, 2023 13:02
-
-
Save EvilFreelancer/d82d34152855afb4bb832b84d427fd87 to your computer and use it in GitHub Desktop.
Простейшее CRUD приложение Go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"database/sql" | |
"encoding/json" | |
"fmt" | |
"log" | |
"net/http" | |
"strconv" | |
_ "github.com/go-sql-driver/mysql" | |
) | |
type Product struct { | |
ID int `json:"id"` | |
Name string `json:"name"` | |
Price float64 `json:"price"` | |
} | |
var db *sql.DB | |
func main() { | |
var err error | |
db, err = sql.Open("mysql", "user:password@/dbname") | |
if err != nil { | |
log.Fatal(err) | |
} | |
defer db.Close() | |
http.HandleFunc("/products", productsHandler) | |
http.HandleFunc("/product/", productHandler) | |
// Тут указано 8080 потому, что приложениям запущенным от обычного пользователя | |
// на уровне операционной системы запрещено работать с портами, номер которых | |
// меньше чем 1024 | |
log.Fatal(http.ListenAndServe(":8080", nil)) | |
} | |
func productsHandler(w http.ResponseWriter, r *http.Request) { | |
if r.Method == http.MethodGet { | |
products, err := getProducts() | |
if err != nil { | |
http.Error(w, err.Error(), http.StatusInternalServerError) | |
return | |
} | |
json.NewEncoder(w).Encode(products) | |
} else if r.Method == http.MethodPost { | |
var p Product | |
err := json.NewDecoder(r.Body).Decode(&p) | |
if err != nil { | |
http.Error(w, err.Error(), http.StatusBadRequest) | |
return | |
} | |
id, err := createProduct(p) | |
if err != nil { | |
http.Error(w, err.Error(), http.StatusInternalServerError) | |
return | |
} | |
fmt.Fprintf(w, "New product ID: %d", id) | |
} else { | |
http.Error(w, "Invalid request method", http.StatusMethodNotAllowed) | |
} | |
} | |
func productHandler(w http.ResponseWriter, r *http.Request) { | |
id, err := strconv.Atoi(r.URL.Path[len("/product/"):]) | |
if err != nil { | |
http.Error(w, err.Error(), http.StatusBadRequest) | |
return | |
} | |
switch r.Method { | |
case http.MethodGet: | |
p, err := getProduct(id) | |
if err != nil { | |
http.Error(w, err.Error(), http.StatusInternalServerError) | |
return | |
} | |
json.NewEncoder(w).Encode(p) | |
case http.MethodPut: | |
var p Product | |
err := json.NewDecoder(r.Body).Decode(&p) | |
if err != nil { | |
http.Error(w, err.Error(), http.StatusBadRequest) | |
return | |
} | |
err = updateProduct(id, p) | |
if err != nil { | |
http.Error(w, err.Error(), http.StatusInternalServerError) | |
return | |
} | |
fmt.Fprintf(w, "Product ID: %d updated", id) | |
case http.MethodDelete: | |
err := deleteProduct(id) | |
if err != nil { | |
http.Error(w, err.Error(), http.StatusInternalServerError) | |
return | |
} | |
fmt.Fprintf(w, "Product ID: %d deleted", id) | |
default: | |
http.Error(w, "Invalid request method", http.StatusMethodNotAllowed) | |
} | |
} | |
func getProducts() ([]Product, error) { | |
rows, err := db.Query("SELECT id, name, price FROM products") | |
if err != nil { | |
return nil, err | |
} | |
defer rows.Close() | |
var products []Product | |
for rows.Next() { | |
var p Product | |
if err := rows.Scan(&p.ID, &p.Name, &p.Price); err != nil { | |
return nil, err | |
} | |
products = append(products, p) | |
} | |
return products, rows.Err() | |
} | |
func getProduct(id int) (Product, error) { | |
var p Product | |
row := db.QueryRow("SELECT id, name, price FROM products WHERE id = ?", id) | |
if err := row.Scan(&p.ID, &p.Name, &p.Price); err != nil { | |
return p, err | |
} | |
return p, nil | |
} | |
func createProduct(p Product) (int, error) { | |
result, err := db.Exec( | |
"INSERT INTO products (name, price) VALUES (?, ?)", | |
p.Name, p.Price, | |
) | |
if err != nil { | |
return 0, err | |
} | |
id, err := result.LastInsertId() | |
if err != nil { | |
return 0, err | |
} | |
return int(id), nil | |
} | |
func updateProduct(id int, p Product) error { | |
_, err := db.Exec( | |
"UPDATE products SET name = ?, price = ? WHERE id = ?", | |
p.Name, p.Price, id, | |
) | |
return err | |
} | |
func deleteProduct(id int) error { | |
_, err := db.Exec("DELETE FROM products WHERE id = ?", id) | |
return err | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment