modified: main_dc/docker-compose.yml
modified: main_dc/nginx/nginx-ssl.conf modified: main_dc/yalarba/api_es/Dockerfile modified: main_dc/yalarba/api_es/cmd/main.go modified: main_dc/yalarba/api_es/go.mod new file: main_dc/yalarba/api_es/go.sum add api_es for REST API backend to easysite, add config nginx, add server connection from api_es to db_tp
This commit is contained in:
@@ -1,9 +1,226 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/go-chi/chi/v5/middleware"
|
||||
"gorm.io/driver/postgres"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/logger"
|
||||
)
|
||||
|
||||
// Модели для БД
|
||||
type User struct {
|
||||
ID uint `gorm:"primaryKey" json:"id"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
|
||||
Name string `json:"name"`
|
||||
Email string `json:"email"`
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
DBHost string
|
||||
DBPort string
|
||||
DBUser string
|
||||
DBPassword string
|
||||
DBName string
|
||||
AppPort string
|
||||
}
|
||||
|
||||
var db *gorm.DB
|
||||
var config Config
|
||||
|
||||
func main() {
|
||||
fmt.Println("Starting api_es ...")
|
||||
// Загрузка конфигурации
|
||||
config = Config{
|
||||
DBHost: getEnv("DB_HOST", "db"),
|
||||
DBPort: getEnv("DB_PORT", "5432"),
|
||||
DBUser: getEnv("DB_USER", "postgres"),
|
||||
DBPassword: getEnv("DB_PASSWORD", "postgres"),
|
||||
DBName: getEnv("DB_NAME", "mydb"),
|
||||
AppPort: getEnv("APP_PORT", "8081"),
|
||||
}
|
||||
|
||||
// Инициализация БД
|
||||
if err := initDB(); err != nil {
|
||||
log.Fatal("Failed to connect to database:", err)
|
||||
}
|
||||
|
||||
// Автомиграция
|
||||
if err := db.AutoMigrate(&User{}); err != nil {
|
||||
log.Fatal("Failed to migrate database:", err)
|
||||
}
|
||||
|
||||
r := chi.NewRouter()
|
||||
|
||||
// Стандартные middleware
|
||||
r.Use(middleware.Logger)
|
||||
r.Use(middleware.Recoverer)
|
||||
r.Use(middleware.Timeout(60 * time.Second))
|
||||
|
||||
// Маршруты API
|
||||
r.Route("/api", func(r chi.Router) {
|
||||
r.Get("/", handleRoot)
|
||||
r.Get("/users", getUsers)
|
||||
r.Post("/users", createUser)
|
||||
r.Get("/users/{id}", getUser)
|
||||
r.Put("/users/{id}", updateUser)
|
||||
r.Delete("/users/{id}", deleteUser)
|
||||
})
|
||||
|
||||
// Health check
|
||||
r.Get("/health", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(map[string]string{"status": "healthy"})
|
||||
})
|
||||
|
||||
// Запуск сервера
|
||||
log.Printf("Server starting on port %s", config.AppPort)
|
||||
if err := http.ListenAndServe(":"+config.AppPort, r); err != nil {
|
||||
log.Fatal("Failed to start server:", err)
|
||||
}
|
||||
}
|
||||
|
||||
func initDB() error {
|
||||
dsn := fmt.Sprintf("host=%s user=%s password=%s dbname=%s port=%s sslmode=disable TimeZone=UTC",
|
||||
config.DBHost, config.DBUser, config.DBPassword, config.DBName, config.DBPort)
|
||||
|
||||
var err error
|
||||
db, err = gorm.Open(postgres.Open(dsn), &gorm.Config{
|
||||
Logger: logger.Default.LogMode(logger.Info),
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sqlDB, err := db.DB()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Настройка пула соединений
|
||||
sqlDB.SetMaxIdleConns(10)
|
||||
sqlDB.SetMaxOpenConns(100)
|
||||
sqlDB.SetConnMaxLifetime(time.Hour)
|
||||
|
||||
log.Println("Successfully connected to database")
|
||||
return nil
|
||||
}
|
||||
|
||||
func getEnv(key, defaultValue string) string {
|
||||
if value := os.Getenv(key); value != "" {
|
||||
return value
|
||||
}
|
||||
return defaultValue
|
||||
}
|
||||
|
||||
// Обработчики API
|
||||
func handleRoot(w http.ResponseWriter, r *http.Request) {
|
||||
response := map[string]string{
|
||||
"message": "EasySite REST API Server",
|
||||
"version": "1.0.0",
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(response)
|
||||
}
|
||||
|
||||
func getUsers(w http.ResponseWriter, r *http.Request) {
|
||||
var users []User
|
||||
if err := db.Find(&users).Error; err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(users)
|
||||
}
|
||||
|
||||
func createUser(w http.ResponseWriter, r *http.Request) {
|
||||
var user User
|
||||
if err := json.NewDecoder(r.Body).Decode(&user); err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
if err := db.Create(&user).Error; err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
json.NewEncoder(w).Encode(user)
|
||||
}
|
||||
|
||||
func getUser(w http.ResponseWriter, r *http.Request) {
|
||||
id := chi.URLParam(r, "id")
|
||||
var user User
|
||||
|
||||
if err := db.First(&user, id).Error; err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
http.Error(w, "User not found", http.StatusNotFound)
|
||||
} else {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(user)
|
||||
}
|
||||
|
||||
func updateUser(w http.ResponseWriter, r *http.Request) {
|
||||
id := chi.URLParam(r, "id")
|
||||
var user User
|
||||
|
||||
if err := db.First(&user, id).Error; err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
http.Error(w, "User not found", http.StatusNotFound)
|
||||
} else {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
var updateData User
|
||||
if err := json.NewDecoder(r.Body).Decode(&updateData); err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
if err := db.Model(&user).Updates(updateData).Error; err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(user)
|
||||
}
|
||||
|
||||
func deleteUser(w http.ResponseWriter, r *http.Request) {
|
||||
id := chi.URLParam(r, "id")
|
||||
var user User
|
||||
|
||||
if err := db.First(&user, id).Error; err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
http.Error(w, "User not found", http.StatusNotFound)
|
||||
} else {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if err := db.Delete(&user).Error; err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(map[string]string{"message": "User deleted successfully"})
|
||||
}
|
||||
Reference in New Issue
Block a user