Principaux modules Go : API Web Golang avec GORM

MISE À JOUR : À compter du 1er mai 2021, le dépôt central GoCenter a été mis hors service et toutes ses fonctionnalités seront obsolètes. Pour en savoir plus sur la mise hors service des centres, lisez l'article de blog sur la dépréciation

 

Chaque mois, GoCenter décerne aux modules les plus performants un badge Gopher qui reconnaît leur réussite. Cet article mentionne quelques-uns de ces meilleurs modules et leur utilisation dans Go.

Robert Greiseimer a donné le nom de Go au langage du Cloud computing. Bien qu'il ne soit un secret pour personne que Go possède des fonctionnalités solides qui prennent en charge les besoins de l’architecture de microservices, des systèmes distribués et des applications d’entreprise à grande échelle, ce dont on parle moins, c’est que Go a également été conçu en gardant à l'esprit le développement Web dès le départ. D'ailleurs, de nombreux développeurs de la communauté utilisent Go pour le développement full-stack et pour défendre de nouveaux modules et frameworks, qui font de Go un langage solide pour le Web. 

Étudions quelques-unes des façons dont Golang et le monde en expansion des modules Go dirigés par la communauté prennent en charge l’échange de données dans les applications Web. Je vais également montrer comment identifier certains modules de qualité via GoCenter, le proxy de module Go gratuit pour la communauté de développement, et j'examinerai en profondeur l’un de mes préférés.

Golang Aime les Données sur le Web

Go intègre des packages Web sophistiqués dans sa bibliothèque de base. Avec la version récente Golang 1.15, cette bibliothèque de base a été mise à jour avec des améliorations apportées à database/sql, database/sql/driver, net/http et encoding/json qui renforcent la capacité de Go à travailler avec des données Web. Ces modifications ajoutent des limitations qui réduisent le risque d'avoir de grandes quantités de services de données utilisant trop de mémoire stack, et définissent une durée d’inactivité pour les connexions de base de données.

Création de Serveur Web

Le package net/http de Go fait partie de la bibliothèque standard et est conçu pour transporter du code HTML du serveur au client. Il utilise pour cela une interface http.Handler qui crée son propre serveur Web. Cette bibliothèque facilite le développement d’API RESTful, et avec les structures Go, il est possible de mapper les applications Big Data à un certain nombre de bases de données et de types de données différents.

Le lancement du service Web implique l’importation du package net/http et l’écriture de deux fonctions.

package main
 
import (
    ("fmt"
    "log"
    "net/http"
)
 
func homePage(w http.ResponseWriter, r *http.Request){
    fmt.Fprintf(w, "Welcome to the HomePage!")
    fmt.Println("Endpoint Hit: homePage")
}
 
func handleRequests() {
    http.HandleFunc("/", homePage)
    log.Fatal(http.ListenAndServe(":10000", nil))
}
 
func main() {
    handleRequests()
}

 

Ce fichier très simple permet de configurer un serveur Web fonctionnel. Bien sûr, ce serveur n’envoie pas, ne stocke pas et ne récupère pas réellement d’informations du Web vers une base de données. Pour intégrer cette fonctionnalité, nous avons créé une application CRUD de base qui peut CRÉER, LIRE, METTRE À JOUR et SUPPRIMER des informations dans votre API.

Pour en savoir plus sur l’utilisation de ce package pour créer des API RESTful, consultez l'excellent tutoriel d’Elliot Forbes.

JSON

L'utilisation de la bibliothèque principale de Go est une façon d’envoyer et de recevoir des informations encoding/json. Cette bibliothèque facilite la lecture/écriture de données à partir de JSON dans vos applications Go. JSON ou Javascript Object Notation a été conçu pour encoder et décoder des données sur le Web et est beaucoup plus adapté au Web que le XML direct. Grâce aux paires clé:valeur, JSON ressemble davantage à du texte brut. Son format de données lisible peut être utilisé lors de la création de vos applications full-stack, de manière à éviter trop de long code SQL. Bien que JSON facilite l’envoi de données, il a toujours besoin d’un moyen de communiquer avec une base de données comme PostgreSQL. 

ORM Golang

Heureusement, la communauté Go a créé un certain nombre de bibliothèques ORM (Object Relational Mapping) pour permettre aux développeurs Go d’utiliser la syntaxe et l’encodage de paires clé:valeur JSON pour mapper directement vers une base de données SQL comme PostgreSQL. Les ORM permettent aux développeurs d’utiliser leur paradigme de programmation natif pour mapper des données vers SQL. 

Un ORM transforme les informations de votre base de données en objets Golang et vice versa. Lorsque vous travaillez avec un ORM, au lieu d’écrire des requêtes SQL directement dans votre application, vous pouvez mapper vos données beaucoup mieux à l’aide d'une structure Golang telle que celle-ci :

// User struct for my database
type User struct {
   gorm.Model
   firstName    string
   lastName     string
   email        string
   message      string
   profession   string
   age          int
   zipCode      int
}

 

Les ORM ne font pas l'unanimité, car ils créent un niveau d’abstraction à partir des données réelles stockées dans la base de données. Selon la bibliothèque que vous utilisez, un autre inconvénient est que, bien que le SQL soit bien établi, les infrastructures ORM peuvent apparaître et disparaître du jour au lendemain. Mais, dans l’ensemble, j’ai constaté que les ORM facilitent grandement le suivi des données d’applications Web dans Go et réduisent la quantité de codage fastidieux en remplaçant de nombreuses commandes SQL, à l’intérieur de mon application, par quelque chose de plus facile à utiliser. 

Un certain nombre d’ORM Go sont pris en charge et promus dans la communauté, tous disponibles dans GoCenter :

  • XORM : Un cadre ORM simple et puissant pour Go
  • Go-PG : Un client postgreSQL et ORM pour Golang
  • SQLBOILDER : Un outil pour générer un Go ORM adapté à votre schéma de base de données
  • SQLX : Ce n'est pas un ORM, mais un autre excellent outil pour SQL dans Go

GORM : Un « Top Gopher »

GORM est un ORM convivial pour les développeurs créé par Jinzhu Zhang et comptabilisant plus de 19 000 étoiles sur GitHub. Il dispose d’un excellent support communautaire et d’une documentation facile à suivre. GORM fournit des opérations CRUD et peut également être utilisé pour la migration initiale et la création du schéma de base de données. Les autres points forts de GORM sont sa facilité d'extension avec la prise en charge de plugin natif, sa fiabilité aux tests, et le support d’associations 1-1 et 1-N. Gorm prend également en charge sqlite, mysql, postgres et mssql.

Ces fonctionnalités sont l'un des principaux arguments pour lesquels le module GORM a reçu le titre de « Top Gopher » dans GoCenter. Si vous consultez les métadonnées complètes de GoCenter sur le module GORM, vous comprendrez pourquoi :

 

  • Le fichier ReadMe du module vous dirige vers une documentation complète. Nous pouvons en savoir plus sur le code du module via l’onglet GoDoc, qui affiche la documentation générée automatiquement sur les fonctions et plus encore.
  • Les onglets Used By et Metrics de GoCenter montrent que ce module est très apprécié et fiable, avec de nombreux téléchargements, forks, contributeurs et utilisations par d’autres modules Go.
  • L'onglet Security de GoCenter révèle également que la version actuelle de ce module et ses dépendances ne présentent pas de vulnérabilité NVD connue, comme le confirme une analyse approfondie JFrog Xray.

Utilisation de GORM

Imaginons que vous souhaitiez créer une API (ou plus tard, une application Web) qui demande aux utilisateurs de vous fournir leur nom, leur adresse électronique et un court message. Avec GORM, une suite d’étapes assez simple permettrait de mapper cela à une base de données. Les étapes :

  • Configurer votre base de données 
  • Mapper une structure d’utilisateur
  • Se connecter à la base de données
  • Effectuer la migration initiale vers la db
  • Configurer vos fonctions
  • Exécuter l’application

Procédure pas à pas GORM

Imaginons que mon agent immobilier à temps partiel (ou peut-être ma sœur) ait besoin d’une application Web qui peut recueillir et stocker des demandes de renseignements sur les propriétés qu’elle gère dans notre ville natale. La première chose que je devrais faire serait de développer une base de données qui peut stocker des informations utilisateur et une API Web qui peut collecter ces informations via un formulaire de contact, puis accéder ultérieurement à ces informations utilisateur afin qu’elles puissent être lues dans un navigateur. Nous allons passer en revue quelques-unes des principales étapes que j’ai suivies pour développer ce type d’application.

Importation de mes modules

Tout d’abord, dans notre fichier main.go, nous pouvons importer nos modules avec les commandes suivantes :

$ export GOPROXY=https://gocenter.io
$ go get github.com/jinzhu/gorm
$ go get github.com/mattn/go-sqlite3

 

Variable de Connexion de Base de Données

Créez une variable simple pour la base de données GORM :

var db *gorm.DB

 

Structure Utilisateur

Nous allons créer notre définition de modèle avec une structure Golang qui mappe le nom de l’utilisateur, son adresse électronique et son message. 

// User struct for my db
type User struct {
   gorm.Model
   name    string
   email   string
   message string
}

 

Migration Initiale pour la Base de Données

J’ai nommé ma base de données sqlite project.db et je peux utiliser la fonctionnalité AutoMigrate de GORM avec une fonction qui ressemble à ceci :

// InitialMigration for project with db.AutoMigrate
func InitialMigration() {
   db, err = gorm.Open("sqlite3", "project.db")
   if err != nil {
       fmt.Println(err.Error())
       panic("Failed to connect to database")
   }
   defer db.Close()
 
   db.AutoMigrate(&User{})
}

 

Fonction de Gestionnaire d’Affichage

Cela nous permettra de voir les données de l’API dans le navigateur :

func viewHandler(writer http.ResponseWriter, request *http.Request) {
   placeholder := []byte("Successfully connected to the database...")
   _, err := writer.Write(placeholder)
   check(err)
}

 

Fonctionnalité de l’API

L’API utilise quatre fonctions principales qui nous permettront de trouver/obtenir des utilisateurs, d’en ajouter, d'en supprimer et de mettre à jour les informations utilisateur dans la base de données. Ces fonctions peuvent être décrites comme suit :

  • func allUsers
  • func newUser
  • func deleteUser
  • func updateUser

Par exemple, cette fonction se connectera à la base de données et affichera toutes les entrées pour les utilisateurs :

func allUsers(w http.ResponseWriter, r *http.Request) {
   db, err := gorm.Open("sqlite3", "project.db")
   if err != nil {
       panic("failed to connect database")
   }
   defer db.Close()
 
   var users []User
   db.Find(&users)
   fmt.Println("{}", users)
 
   json.NewEncoder(w).Encode(users)
}

 

Routeur

Une fois que chaque fonction ci-dessus est créée, la fonction pour gérer le routage ressemblerait à ceci :

func handleRequests() {
   myRouter := mux.NewRouter().StrictSlash(true)
   myRouter.HandleFunc("/users", allUsers).Methods("GET")
   myRouter.HandleFunc("/user/{name}", deleteUser).Methods("DELETE")
   myRouter.HandleFunc("/user/{name}/{email}", updateUser).Methods("PUT")
   myRouter.HandleFunc("/user/{name}/{email}", newUser).Methods("POST")
   myRouter.HandleFunc("/user/{name}/{email}/{message}", updateUser).Methods("PUT")
   myRouter.HandleFunc("/user/{name}/{email}/{message}", newUser).Methods("POST")
   log.Fatal(http.ListenAndServe(":8081", myRouter))
}

 

Fonction Principale

Enfin, vous pouvez exécuter l’application en plaçant les éléments suivants dans votre fonction principale :

func main() {
   fmt.Println("GORM API Project Started")
   initialMigration()
   handleRequests()
}

 

Exécutez l'Application

Puis avec go run main.go, nous verrons la réponse :

GORM API Project Started

Et lorsque je publie (POST) quelques requêtes sur mon API, je peux obtenir (GET) cette demande et voir les données dans le navigateur :

Approfondissez vos Connaissances

En tant que développeur Go utilisant GORM pour la première fois, je trouve qu'il a fortement facilité la migration et le mappage des données vers une base de données sqlite. Le code ci-dessus est un simple instantané pour vous permettre de démarrer.

Pour plus d’informations sur l’utilisation de GORM pour créer des API, consultez cet excellent tutoriel complet avec vidéo réalisé Elliot Forbes.  N’oubliez pas de remercier Elliot sur Twitter pour son merveilleux tutoriel qui couvre tous les aspects des API Golang. 

GORM v2 est également publié désormais et est utilisé pour les tests publics. 

Conclusion

Les points forts de Go dans le développement d’API Web incluent sa vitesse et son évolutivité ; un point assez important à mesure que l’ère du Machine Learning devient courante. Go a été construit à l’ère des processeurs multicœurs et utilise des goroutines pour créer des threads sur des tâches simultanément via plusieurs canaux sur plusieurs processeurs. Cela signifie qu’il peut gérer l’échelle et l’infrastructure nécessaires pour les applications de données volumineuses, et qu'il peut gérer des millions de requêtes HTTP simultanément. Il est également typé statiquement et sa syntaxe stricte rend le débogage beaucoup plus facile, tout en le protégeant contre les erreurs que des langages moins stricts, avec d’énormes bibliothèques comme Javascript, pourraient introduire. C’est pourquoi des entreprises, d’Uber à DropBox, utilisent Go comme langage de choix pour les API et pour faire évoluer leurs applications Web. 

Si vous souhaitez utiliser les capacités de l’API de Go, la création de votre propre API Web à l’aide d’ORM tels que GORM est un excellent point de départ.