Skip to content

Instantly share code, notes, and snippets.

@EvilFreelancer
Created May 13, 2023 13:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save EvilFreelancer/7da51129f992ab71c21784cf6a35cc78 to your computer and use it in GitHub Desktop.
Save EvilFreelancer/7da51129f992ab71c21784cf6a35cc78 to your computer and use it in GitHub Desktop.
Простейшее CRUD приложение Go (вариант 2)
package main
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
}
package main
import (
"database/sql"
"encoding/json"
"fmt"
"log"
"net/http"
"strconv"
_ "github.com/go-sql-driver/mysql"
)
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)
}
}
package main
type Product struct {
ID int `json:"id"`
Name string `json:"name"`
Price float64 `json:"price"`
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment