Simplifier la logique de backend avec la génération de code en Go

Simplifier la logique de backend avec la génération de code en Go

Le développement de backend accumule vite du code répétitif, surtout autour des requêtes de base de données et des serveurs d'API. Écrire ce code à la main est lent et facile à casser. Les outils de génération de code (codegen) transforment une spécification déclarative en code Go typé, sans que vous ayez à le maintenir à la main.

Cet article présente deux outils :

Pourquoi utiliser la génération de code ?

Génération de SQL avec sqlc

Qu'est-ce que sqlc ?

sqlc lit vos fichiers .sql et génère des fonctions Go qui exécutent ces requêtes avec des paramètres et des résultats typés.

Comment utiliser sqlc

  1. Écrivez le schéma et les requêtes.
  2. Définissez l'entrée et la sortie dans sqlc.yaml.
  3. Exécutez sqlc generate.

Exemple

Supposons que vous ayez une table users :

-- schema.sql
CREATE TABLE users (
    id SERIAL PRIMARY KEY,
    name TEXT NOT NULL,
    email TEXT UNIQUE NOT NULL
);

Et une requête qui récupère un utilisateur par e-mail :

-- queries.sql
-- name: GetUserByEmail :one
SELECT id, name, email FROM users WHERE email = $1;

La configuration sqlc.yaml :

version: "1"
packages:
  - name: "db"
    path: "./db"
    queries: "./queries.sql"
    schema: "./schema.sql"
    engine: "postgresql"

Exécutez :

sqlc generate

sqlc produit une méthode comme celle-ci :

func (q *Queries) GetUserByEmail(ctx context.Context, email string) (User, error)

Utilisez-la dans le backend :

user, err := dbQueries.GetUserByEmail(ctx, "alice@example.com")
if err != nil {
    // handle error
}
fmt.Println("User:", user.Name)

La manipulation manuelle du texte SQL et le balayage des lignes disparaissent. Le code est plus propre et plus sûr.

Génération du serveur avec oapi-codegen

Qu'est-ce qu'oapi-codegen ?

oapi-codegen lit une spécification OpenAPI et génère du code serveur et client en Go. Il crée les interfaces et les types de requête et de réponse. Il ne vous reste qu'à implémenter la logique métier.

Comment utiliser oapi-codegen

  1. Définissez l'API dans un fichier OpenAPI YAML ou JSON.
  2. Exécutez oapi-codegen.
  3. Implémentez les méthodes de l'interface générée.

Exemple

Voici une petite spécification OpenAPI api.yaml :

openapi: 3.0.0
info:
  title: User API
  version: 1.0.0
paths:
  /users/{email}:
    get:
      summary: Get user by email
      parameters:
        - name: email
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: User found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/User"
        "404":
          description: User not found
components:
  schemas:
    User:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string
        email:
          type: string

Générez le code serveur :

oapi-codegen -generate types,server -package api -o api.gen.go api.yaml

Cela produit les types de requête et de réponse, comme le struct User, ainsi qu'une interface ServerInterface avec une méthode :

GetUsersEmail(ctx context.Context, email string) (api.User, error)

Implémentez l'interface :

type ServerImpl struct {
    db *db.Queries
}
 
func (s *ServerImpl) GetUsersEmail(ctx context.Context, email string) (api.User, error) {
    user, err := s.db.GetUserByEmail(ctx, email)
    if err != nil {
        return api.User{}, err
    }
    return api.User{
        Id:    int64(user.ID),
        Name:  user.Name,
        Email: user.Email,
    }, nil
}

Branchez le serveur :

router := api.NewRouter(&ServerImpl{db: dbQueries})
http.ListenAndServe(":8080", router)

Bénéfices de la combinaison de sqlc et d'oapi-codegen

Conclusion

sqlc et oapi-codegen ensemble automatisent l'accès à la base de données et le code du serveur d'API dans un backend Go. Vous écrivez moins de code répétitif et vous tombez sur moins d'erreurs à l'exécution. L'attention reste sur la logique centrale de l'application.

© Melvin Laplanche - All rights reserved.