Maison >développement back-end >Golang >Calculatrice Backend-API In Go
De retour avec un autre mini-projet, cette fois avec un outil API backend de calculatrice écrit en Go !
J'ai récemment terminé un projet visant à créer une API HTTP JSON pour une calculatrice sans état, et laissez-moi vous dire que c'était beaucoup plus amusant (et un peu plus difficile) que ce à quoi je m'attendais. En apparence, cela peut paraître simple : « Hé, c'est juste une calculatrice, n'est-ce pas ? Mais une fois que vous avez plongé, vous commencez à découvrir tous les détails essentiels qui rendent une API véritablement prête pour la production.
Alors laissez-moi partager le processus, les leçons apprises et ce que je modifierais si je devais recommencer.
~ Code source : Trouvé ici
La mission était simple : créer une API pour une calculatrice qui ne stocke aucune donnée : pas de bases de données, pas de mise en cache en mémoire. Chaque calcul se produit de manière isolée. Apatride. Faire le ménage. Simple. L'API suit une spécification OpenAPI, qui présente tous les points de terminaison et les comportements attendus.
Validation des entrées
L'une des premières leçons que j'ai apprises a été l'importance de la validation des entrées. Vous ne pouvez pas faire confiance aux utilisateurs, même avec quelque chose d’aussi basique que les mathématiques. Par exemple :
Que se passe-t-il si quelqu'un envoie un non-numéro ? Boum.
Et pourquoi pas une division par zéro ? Double boum.
Pour gérer cela, je me suis assuré que chaque entrée était nettoyée et validée avant même que l'API ne pense à la traiter. Si quelque chose n'allait pas, l'utilisateur recevait un message d'erreur utile et convivial tel que :
{ "error": "Division by zero is not allowed. Please provide a valid denominator." }
Personne n'aime les messages énigmatiques « 500 Server Error ».
Journalisation pour le débogage
Vous connaissez le dicton « Les bûches sont votre meilleur ami » ? C'est vrai. J'ai implémenté la journalisation structurée à l'aide d'un package Go golang.org/x/exp/slog, et cela m'a fait gagner beaucoup de temps. Chaque demande a été enregistrée avec des détails tels que :
Voici un extrait de la façon dont je l'ai configuré pour les journaux de texte :
logger := slog.New(slog.NewTextHandler(os.Stdout, nil))
Ou pour les journaux JSON (qui sont parfaits pour l'intégration avec des outils de surveillance) :
logger := slog.New(slog.NewJSONHandler(os.Stdout, nil))
Avoir ces journaux à portée de main a facilité le débogage lorsque quelque chose ne fonctionnait pas comme prévu.
Je n'avais pas initialement prévu que cette API soit utilisée dans une application basée sur un navigateur, mais au fur et à mesure que le projet évoluait, il est devenu clair que CORS (Cross-Origin Resource Sharing) était nécessaire.
À l'aide du package github.com/rs/cors, j'ai rapidement ajouté les en-têtes requis pour permettre aux clients basés sur un navigateur d'interagir avec l'API.
{ "error": "Division by zero is not allowed. Please provide a valid denominator." }
1) net/http : la bibliothèque standard de Go pour la configuration du serveur HTTP et le routage des requêtes.
2) encoding/json : pour gérer l'encodage/décodage JSON pour les requêtes et les réponses.
3) golang.org/x/exp/slog : pour enregistrer chaque demande au format texte ou JSON.
4) github.com/rs/cors : pour gérer les demandes d'origine croisée pour les intégrations Web.
Eh bien, j'ai créé quelques gestionnaires pour ces calculs, ils sont de nature assez basique et se concentrent principalement sur les fonctionnalités de base des calculs (addition, soustraction, division et multiplication).
logger := slog.New(slog.NewTextHandler(os.Stdout, nil))
En dehors de cela, gérer mes requêtes HTTP avec le célèbre package net/http était simple et il existe de nombreux exemples de différentes manières de procéder. Mon cas était très simple et j'avais juste besoin de fournir du HTTP, en gérant le rédacteur de la réponse et la requête.
logger := slog.New(slog.NewJSONHandler(os.Stdout, nil))
Voici quelques exemples de cas d'utilisation :
c := cors.New(cors.Options{ AllowedOrigins: []string{"*"}, AllowedMethods: []string{"GET", "POST", "OPTIONS"}, AllowedHeaders: []string{"Content-Type"}, AllowCredentials: true, })
Demandes :
//handlers.go func AddHandler(logger *slog.Logger) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { handleOperation(logger, w, r, func(a, b float64) float64 { return a + b }) } } func SubtractHandler(logger *slog.Logger) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { handleOperation(logger, w, r, func(a, b float64) float64 { return a - b }) } } func MultiplyHandler(logger *slog.Logger) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { handleOperation(logger, w, r, func(a, b float64) float64 { return a * b }) } } func DivideHandler(logger *slog.Logger) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { handleOperation(logger, w, r, func(a, b float64) float64 { if b == 0 { panic("division by zero") } return a / b }) } }
Ouais ! C'est à peu près ça ! C'était un mini-projet rapide et amusant que j'ai apprécié ! N'hésitez pas à l'essayer et à l'améliorer comme vous le souhaitez.
À la prochaine fois, bravo ! ? ?
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!