コードを理解し、拡張しやすい方法で整理します。一般的な構造には、コードをモデル、ハンドラー、ルート、ミドルウェア、ユーティリティ、構成などのフォルダーに分割することが含まれます。
構造例:
go-rest-api/ |-- main.go |-- config/ | |-- config.go |-- handlers/ | |-- user.go |-- models/ | |-- user.go |-- routes/ | |-- routes.go |-- middlewares/ | |-- logging.go |-- utils/ | |-- helpers.go
構成設定 (データベース資格情報、ポート番号など) を環境変数または構成ファイルに保存します。 viper などのパッケージを使用して構成を管理します。
config/config.go:
package config import ( "github.com/spf13/viper" "log" ) type Config struct { Port string DB struct { Host string Port string User string Password string Name string } } var AppConfig Config func LoadConfig() { viper.SetConfigName("config") viper.AddConfigPath(".") viper.AutomaticEnv() if err := viper.ReadInConfig(); err != nil { log.Fatalf("Error reading config file, %s", err) } err := viper.Unmarshal(&AppConfig) if err != nil { log.Fatalf("Unable to decode into struct, %v", err) } }
常にエラーを適切に処理します。意味のあるエラー メッセージと HTTP ステータス コードを返します。
handlers/user.go:
func GetUserHandler(w http.ResponseWriter, r *http.Request) { params := mux.Vars(r) id, err := strconv.Atoi(params["id"]) if err != nil { http.Error(w, "Invalid user ID", http.StatusBadRequest) return } user, err := findUserByID(id) if err != nil { http.Error(w, "User not found", http.StatusNotFound) return } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(user) }
ロギング、認証、その他の横断的な問題にミドルウェアを使用します。
middlewares/logging.go:
package middlewares import ( "log" "net/http" "time" ) func LoggingMiddleware(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { start := time.Now() next.ServeHTTP(w, r) log.Printf("%s %s %s", r.Method, r.RequestURI, time.Since(start)) }) }
main.go または Routes/routes.go:
r.Use(middlewares.LoggingMiddleware)
適切な JSON エンコードとデコードを使用します。受信した JSON データを検証して、予想される構造を満たしていることを確認します。
handlers/user.go:
func CreateUserHandler(w http.ResponseWriter, r *http.Request) { var user models.User if err := json.NewDecoder(r.Body).Decode(&user); err != nil { http.Error(w, "Invalid input", http.StatusBadRequest) return } // Validate user data... users = append(users, user) w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(user) }
データベースを使用してデータを保存します。 ORM には gorm 、生の SQL クエリには sqlx などのパッケージを使用します。
models/user.go:
package models import "gorm.io/gorm" type User struct { gorm.Model Name string `json:"name"` Email string `json:"email"` }
main.go:
package main import ( "github.com/yourusername/go-rest-api/config" "github.com/yourusername/go-rest-api/routes" "gorm.io/driver/postgres" "gorm.io/gorm" "log" "net/http" ) func main() { config.LoadConfig() dsn := "host=" config.AppConfig.DB.Host " user=" config.AppConfig.DB.User " password=" config.AppConfig.DB.Password " dbname=" config.AppConfig.DB.Name " port=" config.AppConfig.DB.Port " sslmode=disable" db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{}) if err != nil { log.Fatalf("Could not connect to the database: %v", err) } r := routes.NewRouter(db) log.Println("Starting server on port", config.AppConfig.Port) log.Fatal(http.ListenAndServe(":" config.AppConfig.Port, r)) }
ロギングを改善するには、logrus や zap などの構造化ロギング ライブラリを使用します。
middlewares/logging.go:
package middlewares import ( "github.com/sirupsen/logrus" "net/http" "time" ) func LoggingMiddleware(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { start := time.Now() next.ServeHTTP(w, r) logrus.WithFields(logrus.Fields{ "method": r.Method, "url": r.URL.Path, "time": time.Since(start), }).Info("handled request") }) }
HTTPS の使用、入力の検証とサニタイズ、適切な認証と認可の実装により、API の安全性を確保します。
既存のクライアントを中断せずに変更を処理できるように API のバージョンを設定します。これを行うには、URL にバージョンを含めます (/api/v1/users.
など)。Swagger や Postman などのツールを使用して API を文書化し、開発者に明確な使用手順を提供します。
これらのベスト プラクティスに従うことで、Go で堅牢かつ保守可能でスケーラブルな RESTful API を作成できます。
免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。
Copyright© 2022 湘ICP备2022001581号-3