Maison >développement back-end >Golang >API Rest Full - Golang (meilleures pratiques)

API Rest Full - Golang (meilleures pratiques)

王林
王林original
2024-07-28 07:09:43939parcourir

Rest Full API - Golang (Best Practices)

1. Structure du projet

Organisez votre code de manière à le rendre facile à comprendre et à étendre. Une structure courante consiste à séparer votre code en dossiers tels que les modèles, les gestionnaires, les routes, les middlewares, les utils et la configuration.

Exemple de structure :

go-rest-api/
|-- main.go
|-- config/
|   |-- config.go
|-- handlers/
|   |-- user.go
|-- models/
|   |-- user.go
|-- routes/
|   |-- routes.go
|-- middlewares/
|   |-- logging.go
|-- utils/
|   |-- helpers.go

2. Configuration de l'environnement

Stockez les paramètres de configuration (comme les informations d'identification de la base de données, les numéros de port, etc.) dans des variables d'environnement ou des fichiers de configuration. Utilisez un package comme viper pour gérer les configurations.

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)
    }
}

3. Gestion des erreurs

Toujours gérer les erreurs de manière appropriée. Renvoie des messages d'erreur significatifs et des codes d'état 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)
}

4. Intergiciels

Utilisez des middlewares pour la journalisation, l'authentification et d'autres problèmes transversaux.

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))
    })
}

Dans main.go ou routes/routes.go :

r.Use(middlewares.LoggingMiddleware)

5. Gestion JSON

Utilisez le codage et le décodage JSON appropriés. Validez les données JSON entrantes pour vous assurer qu'elles répondent à la structure attendue.

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)
}

6. Accès à la base de données

Utilisez une base de données pour stocker vos données. Utilisez un package comme gorm pour ORM ou sqlx pour les requêtes SQL brutes.

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))
}

7. Journalisation

Utilisez une bibliothèque de journalisation structurée comme logrus ou zap pour une meilleure journalisation.

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")
    })
}

8. Sécurité

Assurez-vous que votre API est sécurisée en utilisant HTTPS, en validant et en nettoyant les entrées, et en mettant en œuvre une authentification et une autorisation appropriées.

9. Gestion des versions

Versionnez votre API pour gérer les modifications sans interrompre les clients existants. Cela peut être fait en incluant la version dans l'URL, telle que /api/v1/users.

10.Documents

Documentez votre API à l'aide d'outils tels que Swagger ou Postman pour fournir des instructions d'utilisation claires aux développeurs.

En suivant ces bonnes pratiques, vous pouvez créer une API RESTful robuste, maintenable et évolutive dans Go.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn