Développement web avec Go
Créer un serveur HTTP simple avec le package net/http
Go fournit un package standard, net/http, permettant de créer rapidement un serveur HTTP. Ce package est simple à utiliser et permet de gérer les requêtes et réponses de manière efficace. Il est largement utilisé pour la création d’API, de services web et d’applications backend.
1. Mise en place d’un serveur HTTP minimal
Le package net/http permet de créer un serveur HTTP capable de gérer différentes requêtes. Cette section décrit la mise en place d’un serveur de base en ajoutant quelques améliorations pour le rendre plus robuste et structuré.
a. Définition de la structure du serveur
Un serveur HTTP doit être capable de répondre aux requêtes tout en gérant les erreurs éventuelles. Pour cela, il est recommandé de structurer le code en plusieurs fonctions distinctes.
package main
import (
"fmt"
"log"
"net/http"
)
// handler racine, affiche un message de bienvenue
func homeHandler(w http.ResponseWriter, r *http.Request) {
if _, err := fmt.Fprintln(w, "Bienvenue sur le serveur!");
err != nil{
log.Printf("Erreur lors de l'écriture de la réponse
dans homeHandler : %v", err)
Http.Error(w, "Erreur interne du serveur",
http.StatusInternalServerError)
return
}
}
// handler pour une page d'information
func infoHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Informations sur le serveur HTTP en Go.")
// fonction d'initialisation du serveur
func startServer() {
http.HandleFunc("/", homeHandler)
http.HandleFunc("/info", infoHandler)
port := ":8080"
log.Println("Le serveur démarre sur http://localhost"...Gérer les requêtes et les réponses
Lors de la création d’un serveur HTTP en Go, la gestion des requêtes et des réponses est essentielle pour interagir avec les clients. Le package net/http offre des outils intégrés pour récupérer les informations des requêtes et structurer les réponses de manière efficace.
1. Récupérer les informations d’une requête HTTP
Lorsqu’un client envoie une requête HTTP, il transmet diverses informations que le serveur peut exploiter. Ces données incluent la méthode HTTP utilisée, les en-têtes de la requête, les paramètres de l’URL et éventuellement un corps de requête.
a. Lire la méthode HTTP
La méthode HTTP (GET, POST, PUT, DELETE, etc.) indique l’intention de la requête. Le serveur doit identifier cette méthode pour traiter correctement la requête.
package main
import (
"fmt"
"log"
"net/http"
)
// Handler qui affiche la méthode HTTP utilisée
func methodHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Méthode HTTP reçue : %s", r.Method)
}
func main() {
http.HandleFunc("/method", methodHandler)
port := ":8080"
log.Println("Serveur démarré sur http://localhost" + port)
if err := http.ListenAndServe(port, nil); err != nil {
log.Fatalf("Erreur serveur : %v", err)
}
}
Test avec curl :
curl -X GET http://localhost:8080/method
curl -X POST http://localhost:8080/method
b. Lire les en-têtes de requête
Les en-têtes HTTP contiennent des métadonnées sur la requête, comme le type de contenu, l’agent utilisateur ou des informations d’authentification....
Sérialisation des données avec JSON (encoding/json)
Go intègre le package encoding/json, qui permet de sérialiser et désérialiser des données au format JSON. Ce format est couramment utilisé pour l’échange de données entre applications web et API.
1. Convertir une structure en JSON
Le format JSON est largement utilisé pour échanger des données entre un serveur et un client. La conversion d’une structure Go en JSON est essentielle pour générer des réponses API ou stocker des données sous un format standardisé.
a. Sérialisation d’une structure simple
Le package encoding/json fournit json.Marshal() pour convertir une structure Go en JSON.
package main
import (
"encoding/json"
"fmt"
"log"
)
// Définition d'une structure utilisateur
type User struct {
Name string `json:"name"`
Age int `json:"age"`
Email string `json:"email"`
}
func main() {
user := User{Name: "Alice", Age: 30, Email: "alice@example.com"}
jsonData, err := json.Marshal(user)
if err != nil {
log.Fatalf("Erreur de sérialisation JSON : %v", err)
}
fmt.Println("Données JSON :", string(jsonData))
}
b. Formatage du JSON pour la lisibilité
Par défaut, json.Marshal() génère une sortie compacte. Pour un format lisible, on utilise json.MarshalIndent().
jsonPretty, err := json.MarshalIndent(user, "", " ")
if err != nil {
log.Fatalf("Erreur de sérialisation JSON : %v", err)
}
fmt.Println("Données JSON formatées :\n", string(jsonPretty))
c. Ignorer des champs lors de la conversion
Certains champs peuvent être exclus du JSON en utilisant l’option...
Frameworks populaires : Gin, Echo
Go propose plusieurs frameworks web facilitant le développement d’applications HTTP. Parmi les plus populaires, Gin et Echo se distinguent par leur simplicité et leur rapidité. Bien qu’ils s’appuient tous deux sur le package standard net/http, ils étendent ses capacités en offrant des fonctionnalités avancées telles que la sérialisation JSON automatique et une gestion native des middlewares.
Ces derniers simplifient considérablement la mise en place de briques logicielles transversales, notamment pour la sécurité (authentification, gestion du CORS) ou le monitoring.
1. Gin : un framework performant et minimaliste
Gin est un framework web performant et minimaliste conçu pour faciliter le développement d’applications HTTP en Go. Il se distingue par un routeur extrêmement rapide, optimisé grâce à une structure en arbre radix (Radix Tree), qui garantit des performances constantes même avec un grand nombre de routes. Il offre également une gestion simplifiée des requêtes et des réponses, ainsi qu’un support natif de la sérialisation JSON.
a. Installation de Gin
L’installation du framework se fait avec la commande suivante :
go get -u github.com/gin-gonic/gin
b. Création d’un serveur avec Gin
Voici un exemple de serveur HTTP minimal utilisant Gin :
package main
import (
"github.com/gin-gonic/gin"
"net/http"
)
func main() {
router := gin.Default()
// Définition d'une route GET sur la racine
router.GET("/", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"message": "Bienvenue sur Gin!"})
})
router.Run(":8080") // Démarre le serveur sur le port 8080
}
c. Gestion des routes avec des paramètres
Gin permet de récupérer facilement des paramètres passés dans l’URL.
func userHandler(c *gin.Context) {
username := c.Param("username")...Cas pratique : construire une API REST simple
Cette section décrit la création d’une API REST complète utilisant le framework Gin. L’API permettra de gérer une liste d’articles avec les opérations CRUD (Create, Read, Update, Delete).
1. Installation et structure du projet
Avant de commencer, assurez-vous que Gin est installé :
go get -u github.com/gin-gonic/gin
Organisation du projet :
api/
├── main.go
2. Définition du modèle et des données
Le modèle Article représente un élément de l’API. Les articles sont stockés dans une liste qui simule une base de données. Cette approche simplifiée est réservée au développement ou à titre d’exemple ; pour un environnement de production, on utilise un système de gestion de base de données robuste, de type SQL (comme PostgreSQL) ou NoSQL (comme MongoDB).
package main
import (
"github.com/gin-gonic/gin"
"net/http"
)
// Définition de la structure Article
type Article struct {
ID int `json:"id"`
Title string `json:"title"`
Content string `json:"content"`
}
// Liste d'articles simulant une base de données
var articles = []Article{
{ID: 1, Title: "Introduction à Gin", Content: "Gin est un
framework rapide."},
{ID: 2, Title: "Créer une API REST", Content: "Gin facilite la
gestion des routes."}...