Passer au contenu principal
Didit lève 7,5 M$ pour bâtir l'infrastructure pour l'identité et la fraude
Didit
Retour au blog
Blog · 6 mars 2026

Maîtriser la gestion des erreurs et les stratégies de réessai de l'API Didit en Go (FR)

Pour des intégrations robustes de l'API Didit en Go, une gestion sophistiquée des erreurs et des stratégies de réessai sont essentielles. Ce guide explore les meilleures pratiques, de la compréhension des limites de débit de.

Par DiditMis à jour le
didit-api-error-handling-retries-go.png

Comprendre les limites de débit de DiditImplémentez une limitation côté client et un backoff exponentiel pour les réponses 429, en utilisant les en-têtes X-RateLimit-Limit, X-RateLimit-Remaining et X-RateLimit-Reset pour éviter les interruptions de service.

Différencier les types d'erreursDistinguez les erreurs transitoires (par exemple, problèmes réseau, indisponibilité du service) et permanentes (par exemple, clés API invalides, requêtes mal formées) pour appliquer une logique de réessai appropriée ou échouer rapidement.

Implémenter des mécanismes de réessai robustesUtilisez des boucles de réessai structurées avec un backoff exponentiel, une gigue et un nombre maximal de tentatives pour gérer les échecs transitoires avec élégance, améliorant la fiabilité des opérations critiques comme la création de session.

L'approche "développeur d'abord" de Didit simplifie l'intégrationDidit fournit une documentation API claire, des en-têtes de limitation de débit spécifiques et une architecture modulaire, permettant aux développeurs Go de construire des flux de vérification d'identité résilients avec facilité et confiance.

L'intégration d'API tierces est un pilier du développement d'applications modernes, et la vérification d'identité ne fait pas exception. Lorsque vous travaillez avec des services critiques comme la plateforme d'identité de Didit, il est primordial de garantir que votre intégration est résiliente aux fluctuations du réseau, aux problèmes de service et aux limites de débit. Ce guide explore les stratégies avancées de gestion des erreurs et de réessai spécifiquement adaptées aux intégrations de l'API Didit en utilisant Go, vous aidant à construire des systèmes robustes et fiables.

Comprendre le paysage des erreurs de l'API Didit

Avant d'implémenter une logique de réessai, il est crucial de comprendre les types d'erreurs que vous pourriez rencontrer. L'API de Didit, comme de nombreux services bien conçus, communique divers états via des codes de statut HTTP. Alors que les codes 2xx standard indiquent le succès, vous vous concentrerez principalement sur les 4xx (erreurs client) et 5xx (erreurs serveur), et en particulier le 429 (Trop de requêtes).

La limitation de débit de Didit et ce que cela signifie pour vous

Didit applique la limitation de débit pour maintenir la stabilité de l'API. C'est un aspect critique à gérer dans votre intégration. Par exemple, les points de terminaison GET ont généralement une limite globale de 300 requêtes par minute et par application, avec des points de terminaison spécifiques comme session-decision (100 rpm) ou session-v2-create (600 rpm) ayant leurs propres limites, potentiellement plus strictes. Lorsque vous atteignez une limite de débit, Didit répond avec un code de statut 429 Too Many Requests et inclut des en-têtes utiles :

  • X-RateLimit-Limit : Le nombre maximal de requêtes autorisées dans la fenêtre actuelle.
  • X-RateLimit-Remaining : Le nombre de requêtes restantes dans la fenêtre actuelle.
  • X-RateLimit-Reset : L'heure (en secondes epoch) à laquelle la fenêtre de limitation de débit actuelle se réinitialise.
  • Retry-After : (Souvent inclus) Le nombre de secondes à attendre avant de faire une autre requête.

Votre client Go doit surveiller activement ces en-têtes. Lorsque X-RateLimit-Remaining tombe en dessous d'un certain seuil (par exemple, 15 % de X-RateLimit-Limit), vous devez limiter proactivement vos requêtes. Ignorer cela peut entraîner des erreurs 429 persistantes, ce qui affectera la capacité de votre application à créer des sessions de vérification ou à récupérer des résultats de produits comme la vérification d'identité Didit ou le contrôle LAB.

Implémenter des stratégies de réessai robustes avec un backoff exponentiel en Go

Pour les erreurs transitoires (par exemple, délais d'attente réseau, indisponibilité temporaire du service ou 429), les réessais sont essentiels. Cependant, des réessais naïfs peuvent exacerber les problèmes. La référence est le backoff exponentiel avec gigue.

Backoff exponentiel avec gigue

Le backoff exponentiel signifie augmenter le temps d'attente entre les réessais de manière exponentielle. La gigue (ajout d'un petit délai aléatoire) empêche un problème de « harde tonitruante » où de nombreux clients réessayent simultanément après une panne, submergeant à nouveau le service. Voici un exemple conceptuel en Go :

package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"time"
	"math/rand"
)

func callDiditAPIWithRetry(url string, maxRetries int) ([]byte, error) {
	client := &http.Client{Timeout: 10 * time.Second}
	rand.Seed(time.Now().UnixNano())

	for i := 0; i <= maxRetries; i++ {
		resp, err := client.Get(url)
		if err != nil {
			// Gérer les erreurs réseau (par exemple, connexion refusée, délai d'attente)
			fmt.Printf("Tentative %d: Erreur réseau : %v\n", i+1, err)
			if i == maxRetries {
				return nil, fmt.Errorf("échec après %d tentatives : %w", maxRetries, err)
			}
			sleepTime := time.Duration(1<<i)*time.Second + time.Duration(rand.Intn(1000))*time.Millisecond // Backoff exponentiel + gigue
			fmt.Printf("Nouvelle tentative dans %v...\n", sleepTime)
			time.Sleep(sleepTime)
			continue
		}
		defer resp.Body.Close()

		switch resp.StatusCode {
		case http.StatusOK:
			fmt.Printf("Tentative %d: Succès !\n", i+1)
			return ioutil.ReadAll(resp.Body)
		case http.StatusTooManyRequests:
			// Respecter l'en-tête Retry-After si présent
			retryAfter := resp.Header.Get("Retry-After")
			if retryAfter != "" {
				if sleepSeconds, err := time.ParseDuration(retryAfter + "s"); err == nil {
					fmt.Printf("Tentative %d: Limite de débit atteinte. Nouvelle tentative après %v.\n", i+1, sleepSeconds)
					time.Sleep(sleepSeconds)
					continue
				}
			}
			// Retour au backoff exponentiel si Retry-After est manquant ou invalide
			fmt.Printf("Tentative %d: Limite de débit atteinte (429).\n", i+1)
			if i == maxRetries {
				return nil, fmt.Errorf("limite de débit atteinte après %d tentatives", maxRetries)
			}
			sleepTime := time.Duration(1<<i)*time.Second + time.Duration(rand.Intn(1000))*time.Millisecond
			fmt.Printf("Nouvelle tentative dans %v...\n", sleepTime)
			time.Sleep(sleepTime)
			continue
		case http.StatusInternalServerError, http.StatusBadGateway, http.StatusServiceUnavailable, http.StatusGatewayTimeout:
			// Erreurs côté serveur qui pourraient être transitoires
			fmt.Printf("Tentative %d: Erreur serveur %d. Nouvelle tentative.\n", i+1, resp.StatusCode)
			if i == maxRetries {
				return nil, fmt.Errorf("erreur serveur %d après %d tentatives", resp.StatusCode, maxRetries)
			}
			sleepTime := time.Duration(1<<i)*time.Second + time.Duration(rand.Intn(1000))*time.Millisecond
			fmt.Printf("Nouvelle tentative dans %v...\n", sleepTime)
			time.Sleep(sleepTime)
			continue
		default:
			// Erreurs non réessayables (erreurs client 4xx, etc.)
			body, _ := ioutil.ReadAll(resp.Body)
			return nil, fmt.Errorf("erreur API non réessayable : %d %s, réponse : %s", resp.StatusCode, resp.Status, string(body))
		}
	}
	return nil, fmt.Errorf("flux de contrôle inattendu") // Ne devrait pas être atteint
}

func main() {
	// Exemple d'utilisation : Remplacer par un point de terminaison API Didit réel
	// Pour une intégration réelle, vous feriez un POST vers /v3/session/ ou similaire
	// et géreriez l'URL de vérification.
	apiURL := "https://verification.didit.me/health"
	data, err := callDiditAPIWithRetry(apiURL, 5)
	if err != nil {
		fmt.Println("Échec de l'appel API :", err)
	} else {
		fmt.Println("Réponse API :", string(data))
	}
}

Cet extrait montre comment gérer les erreurs réseau, les 429 (en respectant Retry-After) et les erreurs 5xx courantes avec un backoff exponentiel et une gigue. Il montre également comment échouer rapidement pour les erreurs 4xx non réessayables, qui sont généralement dues à une entrée incorrecte et ne se résoudront pas lors d'une nouvelle tentative. C'est crucial pour des opérations comme la création d'une session de vérification en utilisant l'architecture modulaire de Didit.

Implémenter un modèle de coupe-circuit

Alors que les réessais aident à résoudre les problèmes transitoires, réessayer continuellement un service défaillant peut le surcharger davantage ou gaspiller des ressources si le service est réellement en panne. C'est là qu'intervient le modèle de coupe-circuit. Un coupe-circuit surveille les échecs et, s'ils atteignent un certain seuil, « ouvre » le circuit, empêchant de nouvelles requêtes pendant une période définie. Après cette période, il autorise quelques requêtes de test pour voir si le service a récupéré.

En Go, vous pouvez utiliser des bibliothèques comme sony/gobreaker pour implémenter ce modèle :

package main

import (
	"errors"
	"fmt"
	"io/ioutil"
	"net/http"
	"time"

	"github.com/sony/gobreaker"
)

var cb *gobreaker.CircuitBreaker

func init() {
	st := gobreaker.Settings{
		Name:        "DiditAPICircuitBreaker",
		MaxRequests: 3, // Autoriser 3 requêtes en état semi-ouvert
		Interval:    5 * time.Second, // Période pour collecter des données pour les décisions de déclenchement
		Timeout:     10 * time.Second, // Ouvrir le circuit pendant 10 secondes
		ReadyToTrip: func(counts gobreaker.Counts) bool {
			return counts.ConsecutiveFailures > 5 // Déclencher après 5 échecs consécutifs
		},
		OnStateChange: func(name string, from gobreaker.State, to gobreaker.State) {
			fmt.Printf("Coupe-circuit '%s' est passé de %s à %s\n", name, from, to)
		},
	}
	cb = gobreaker.NewCircuitBreaker(st)
}

func callDiditAPIWithCircuitBreaker(url string) ([]byte, error) {
	body, err := cb.Execute(func() (interface{}, error) {
		resp, err := http.Get(url)
		if err != nil {
			return nil, err // Erreur réseau
		}
		defer resp.Body.Close()

		if resp.StatusCode != http.StatusOK {
			// Ne compter que les 5xx et 429 comme des échecs pour le coupe-circuit
			if resp.StatusCode == http.StatusTooManyRequests || resp.StatusCode >= http.StatusInternalServerError {
				return nil, fmt.Errorf("L'API a retourné le statut %d", resp.StatusCode)
			}
			// Pour les autres erreurs 4xx, nous pourrions ne pas vouloir déclencher le coupe-circuit, mais toujours retourner une erreur
			bodyBytes, _ := ioutil.ReadAll(resp.Body)
			return nil, fmt.Errorf("erreur API non réessayable : %d %s, réponse : %s", resp.StatusCode, resp.Status, string(bodyBytes))
		}

		return ioutil.ReadAll(resp.Body)
	})

	if err != nil {
		if errors.Is(err, gobreaker.ErrOpenState) {
			return nil, fmt.Errorf("le coupe-circuit est ouvert : %w", err)
		}
		return nil, err
	}

	return body.([]byte), nil
}

func main() {
	// Exemple d'utilisation
	apiURL := "https://verification.didit.me/health"
	for i := 0; i < 10; i++ {
		data, err := callDiditAPIWithCircuitBreaker(apiURL)
		if err != nil {
			fmt.Printf("Appel %d échoué : %v\n", i+1, err)
		} else {
			fmt.Printf("Appel %d réussi : %s\n", i+1, string(data))
		}
		time.Sleep(1 * time.Second)
	}
}

La combinaison des coupe-circuits avec un backoff exponentiel garantit que votre application reste réactive et ne surcharge pas un service externe en difficulté. C'est particulièrement important lors de la gestion de demandes de vérification d'identité à volume élevé, telles que celles impliquant la vérification d'identité de Didit ou les vérifications de vitalité passives et actives.

Gestion des échecs de webhook et des résultats asynchrones

L'API de Didit fournit souvent des résultats de manière asynchrone via des webhooks, par exemple, après qu'un utilisateur a terminé un flux de vérification d'identité ou lorsqu'un contrôle LAB est terminé. Votre point de terminaison de webhook doit être robuste. Si votre point de terminaison ne parvient pas à traiter un webhook (par exemple, renvoie un code de statut 5xx), Didit tentera de le livrer à nouveau. Il est crucial de :

  • Accuser réception immédiatement : Renvoyez un code de statut 2xx dès que possible pour signaler une réception réussie, même si le traitement prend plus de temps.
  • Traiter de manière asynchrone : Transférez la charge utile du webhook à un travailleur en arrière-plan ou à une file d'attente de messages (par exemple, Kafka, RabbitMQ) pour le traitement. Cela empêche votre point de terminaison de webhook d'expirer les tentatives de Didit.
  • Idempotence : Assurez-vous que votre logique de traitement de webhook est idempotente. Si Didit réessaie et livre le même webhook plusieurs fois, votre système ne doit le traiter qu'une seule fois pour éviter les actions en double ou les incohérences de données.
  • Vérifier les signatures : Vérifiez toujours la signature du webhook en utilisant votre Clé secrète de webhook depuis la console Didit pour vous assurer que la requête provient réellement de Didit et n'a pas été altérée.

Comment Didit aide

Didit est conçu en tenant compte de l'expérience développeur et de la fiabilité, offrant des fonctionnalités qui simplifient intrinsèquement la gestion avancée des erreurs et les stratégies de réessai pour vos intégrations Go. Notre approche axée sur les développeurs signifie une documentation API claire et complète, un environnement de test instantané et des API épurées qui facilitent l'intégration.

  • Limitation de débit prévisible : Didit définit clairement les limites de débit globales et spécifiques aux points de terminaison, ainsi que les en-têtes HTTP standard (X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, Retry-After) pour guider votre logique de limitation côté client et de backoff. Cette transparence vous permet de construire des mécanismes de réessai optimisés pour des services comme la vérification d'identité et le contrôle LAB.
  • Architecture modulaire : Nos primitives d'identité modulaires vous permettent de construire des flux de travail résilients par conception. Si une vérification spécifique (par exemple, preuve d'adresse) rencontre un problème transitoire, votre flux de travail global peut être configuré pour s'adapter ou réessayer des composants spécifiques sans affecter les étapes de vérification non liées.
  • Fiabilité native de l'IA : Le backend natif de l'IA de Didit est conçu pour l'échelle et la résilience, minimisant les erreurs côté serveur que vous rencontrerez. Cela vous permet de concentrer votre gestion des erreurs sur les problèmes réseau et côté client, plutôt que sur des pannes de service constantes.
  • KYC de base gratuit et tarifs flexibles : Démarrez avec le niveau gratuit de Didit pour le KYC de base, vous permettant de tester minutieusement vos stratégies de gestion des erreurs et de réessai dans un environnement de production sans coûts initiaux. Notre modèle de paiement par vérification réussie aligne davantage notre succès sur le vôtre.

Prêt à commencer ?

Prêt à voir Didit en action ? Obtenez une démo gratuite dès aujourd'hui.

Commencez à vérifier les identités gratuitement avec le niveau gratuit de Didit.

Infrastructure pour l'identité et la fraude.

Une seule API pour le KYC, le KYB, la surveillance des transactions et le screening de portefeuilles. Intégration en 5 minutes.

Demande à une IA de résumer cette page
Gestion des erreurs API Didit & Réessais en Go: Guide.