TP : Intégration de Gorm avec Gin pour une API REST
Vous
Utilisez la bibliothèque Gorm, un ORM (Object-Relational Mapping), pour interagir avec la base de données. Gorm facilite l'accès et la manipulation des données en utilisant Gorm pour la persistance des données.requêtes SQL dans le code Go.
Définir une structure Book qui représente un livre avec les champs suivants :
Créer une connexion à la base de données à l'aide de Gorm.Gorm et configurer le modèle Book pour qu'il corresponde à une table dans la base de données.
Définir les routes de l'API REST avec Gin :
Implémenter les modèleshandlers (fonctions) pour chaque route en utilisant Gorm pour interagir avec la base de données :
books.
POST /books : crée un nouveau livre à partir des données JSON envoyées et l'ajoute à la base de données en utilisant Gorm pour créer un nouvel enregistrement dans la table books.
GET /books/:id : récupère les détails d'un livre spécifique par son identifiant et renvoie les données JSON correspondantes en utilisant Gorm pour récupérer un enregistrement spécifique de la table books.
PUT /books/:id : met à jour les données d'un livre spécifique par son identifiant à partir des données JSON envoyées en utilisant Gorm pour mettre à jour l'enregistrement correspondant dans la table books.
DELETE /books/:id : supprime un livre spécifique par son identifiant de la base de données en utilisant Gorm pour supprimer l'enregistrement correspondant de la table books.
Installez les dépendances nécessaires, y compris Gin et Gorm, en utilisant les commandes suivantes :
go get -u github.com/gin-gonic/gin
go get -u gorm.io/gorm
go get -u gorm.io/driver/mysql
Solution
package main
import (
"github.com/gin-gonic/gin"
"gorm.io/driver/mysql"
"gorm.io/gorm"
"net/http"
"strconv"
)
type Book struct {
ID int `gorm:"primaryKey" json:"id"`
Title string `json:"title"`
Author string `json:"author"`
Year int `json:"year"`
}
var (
db *gorm.DB
err error
books []Book
)
func main() {
dsn := "user:password@tcp(localhost:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"
db, err = gorm.Open(mysql.Open(dsn), &gorm.Config{})
if err != nil {
panic("failed to connect to database")
}
db.AutoMigrate(&Book{})
router := gin.Default()
router.GET("/books", getBooks)
router.POST("/books", createBook)
router.GET("/books/:id", getBook)
router.PUT("/books/:id", updateBook)
router.DELETE("/books/:id", deleteBook)
router.Run(":8080")
}
func getBooks(c *gin.Context) {
db.Find(&books)
c.JSON(http.StatusOK, books)
}
func createBook(c *gin.Context) {
var book Book
if err := c.ShouldBindJSON(&book); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
db.Create(&book)
c.JSON(http.StatusCreated, book)
}
func getBook(c *gin.Context) {
id, _ := strconv.Atoi(c.Param("id"))
var book Book
db.First(&book, id)
if book.ID == 0 {
c.JSON(http.StatusNotFound, gin.H{"error": "Book not found"})
return
}
c.JSON(http.StatusOK, book)
}
func updateBook(c *gin.Context) {
id, _ := strconv.Atoi(c.Param("id"))
var book Book
db.First(&book, id)
if book.ID == 0 {
c.JSON(http.StatusNotFound, gin.H{"error": "Book not found"})
return
}
if err := c.ShouldBindJSON(&book); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
db.Save(&book)
c.JSON(http.StatusOK, book)
}
func deleteBook(c *gin.Context) {
id, _ := strconv.Atoi(c.Param("id"))
var book Book
db.First(&book, id)
if book.ID == 0 {
c.JSON(http.StatusNotFound, gin.H{"error": "Book not found"})
return
}
db.Delete(&book)
c.JSON(http.StatusOK, gin.H{"message": "Book deleted"})
}
Création de la connexion à la base de données : Avant de pouvoir interagir avec la base de données, nous devons créer une connexion en utilisant Gorm et le pilote MySQL. Cela se fait en utilisant la fonction gorm.Open() avec la chaîne de connexion dsn qui contient les informations de connexion telles que le nom d'utilisateur, le mot de passe, l'adresse du serveur et le nom de la base de données.
Définition du modèle Book et migration de la table : Nous définissons la structure Book qui représente un livre et utilisons les tags de struct Gorm pour configurer les détails de la table dans la base de données. Dans cet exemple, nous utilisons le tag primaryKey pour spécifier que le champ ID est la clé primaire de la table. Après avoir défini le modèle, nous utilisons db.AutoMigrate(&Book{}) pour créer ou mettre à jour automatiquement la table dans la base de données.
Définition des routes de l'API REST avec Gin : Nous utilisons le framework Gin pour définir les structuresroutes correspondantesde l'API REST. Nous créons un routeur avec gin.Default() et définissons les routes et les méthodes correspondantes. Les routes sont définies avec les chemins /books, /books/:id, etc., et les méthodes HTTP associées (GET, POST, PUT, DELETE).
Implémentation des handlers pour chaque route : Nous implémentons les handlers (fonctions) qui sont exécutés lorsque les routes sont appelées. Chaque handler utilise Gorm pour effectuer des opérations sur la base de données en fonction de l'action CRUD correspondante.
getBooks récupère tous les enregistrements de la table books en utilisant db.Find(&books) et renvoie la liste des livres en tant que réponse JSON.
Le handler createBook crée un nouveau livre à partir des données JSON envoyées en utilisant c.ShouldBindJSON(&book) pour lier les données JSON à la structure Book. Ensuite, nous utilisons db.Create(&book) pour créer books et renvoyons le livre créé en tant que réponse JSON.
Le handler getBook récupère les détails d'un livre spécifique par son identifiant en utilisant db.First(&book, id) pour trouver le premier enregistrement correspondant dans la table books. Si le livre n'est pas trouvé, nous renvoyons une réponse JSON indiquant que le livre n'a pas été trouvé.
Le handler updateBook met à jour les db.First(&book, id) pour récupérer l'enregistrement correspondant, puis c.ShouldBindJSON(&book) pour lier les données JSON à la structure Book. Ensuite, nous utilisons db.Save(&book) pour mettre à jour l'enregistrement dans la table books et renvoyons le livre mis à jour en tant que réponse JSON.
Le handler deleteBook supprime un livre spécifique par son identifiant en utilisant db.First(&book, id) pour récupérer l'enregistrement correspondant, puis db.Delete(&book) pour supprimer l'enregistrement de la table books. Nous renvoyons ensuite une réponse JSON indiquant que le livre a été supprimé.
Pour chaque handler, nous vérifions également si l'opération de recherche (First() ou Find()) a réussi en vérifiant la valeur de book.ID. Si book.ID est égal à 0, cela signifie que l'enregistrement correspondant n'a pas été trouvé et nous renvoyons une réponse JSON appropriée.
Exécution de l'API sur un port spécifique : Nous utilisons router.Run(":8080") pour exécuter l'API sur le port 8080. Vous pouvez modifier le numéro de port en fonction de vos besoins.