Maison >développement back-end >Golang >Comment accéder à la base de données si les fonctions sont dans des modules différents ?

Comment accéder à la base de données si les fonctions sont dans des modules différents ?

PHPz
PHPzavant
2024-02-10 21:06:10866parcourir

Comment accéder à la base de données si les fonctions sont dans des modules différents ?

L'éditeur PHP Zimo est là pour répondre à une question courante : Comment devez-vous fonctionner si vous accédez à la base de données dans différents modules ? Au cours du processus de développement, nous devons souvent accéder à la base de données dans différents modules fonctionnels, ce qui implique comment gérer les connexions à la base de données et effectuer des opérations sur la base de données. Afin de résoudre ce problème, nous pouvons utiliser diverses méthodes, telles que l'utilisation de variables globales, le mode singleton, l'injection de dépendances, etc. La méthode spécifique choisie dépend des besoins du projet et des habitudes de l'équipe de développement. Ensuite, je présenterai ces méthodes en détail, dans l’espoir d’aider tout le monde.

Contenu de la question

J'essaie d'autoriser en utilisant jwt mais j'ai un problème, lorsque je vérifie l'e-mail de l'e-mail de valeur revendiquée, j'obtiens une erreur 500. Le problème est que la base de données n'est pas encore prête.

Voici le code

Itinéraire des forfaits

package route

import (
    "go_fiber/controller"
    "go_fiber/middleware"


    "github.com/gofiber/fiber/v2"
)

func routeinit(app *fiber.app, usercontroller controller.usercontroller) {
    app.get("/users", middleware.authmiddleware, usercontroller.findall)
    app.post("/login", usercontroller.login)
}

Applications d'emballage

package app

import (
    "database/sql"
    "fmt"
    "go_fiber/helper"
    "os"
    "time"

    _ "github.com/go-sql-driver/mysql"
    "github.com/joho/godotenv"
)

func newdb() *sql.db {

    var (   
        username = envvariable("db_username")
        password = envvariable("db_password")
        host = envvariable("db_host")
        port = envvariable("db_port")
        db_name = envvariable("db_name")
    )

    dns := fmt.sprintf("%s:%s@tcp(%s:%s)/%s?parsetime=true", username, password, host, port, db_name)

    db, err := sql.open("mysql", dns)
    if err != nil {
        panic(err)
    }

    db.setmaxidleconns(10)
    db.setmaxopenconns(100)
    db.setconnmaxidletime(5 * time.minute)
    db.setconnmaxlifetime(60 * time.minute)

    return db
}

Packmaster

package main

import (
    "go_fiber/app"
    "go_fiber/controller"
    "go_fiber/exception"
    "go_fiber/repository"
    "go_fiber/route"
    "go_fiber/service"

    "github.com/go-playground/validator/v10"
    "github.com/gofiber/fiber/v2"
)

func main(){

    var db = app.newdb()
    app := fiber.new()
    app.use(func(c *fiber.ctx) error {
        defer func() {
            if err := recover(); err != nil {
                exception.errorhandler(c, err)
            }
        }()
    
        return c.next()
    })

    validator := validator.new()
    userrepository := repository.newuserrepository()
    userservice := service.newuserservice(userrepository, db, validator)
    usercontroller := controller.newusercontroller(userservice)
    
    route.routeinit(app, usercontroller)

    app.listen(":3000")
}

Middleware d'emballage

package middleware

import (
    "database/sql"
    "errors"
    "fmt"
    "go_fiber/exception"
    "log"
    "os"
    "time"

    "github.com/gofiber/fiber/v2"
    "github.com/golang-jwt/jwt/v4"
)

func authmiddleware(c *fiber.ctx) error{
    tokenstring := c.cookies("authorization") 

    log.printf("(middleware) token : %v", tokenstring)

    if tokenstring == "" {
        panic(exception.newuserunauthorized(errors.new("user unauthorized").error()))
    }

    token, err := jwt.parse(tokenstring, func(token *jwt.token) (interface{}, error) {
        if _, ok := token.method.(*jwt.signingmethodhmac); !ok {
            return nil, fmt.errorf("unexpected signing method :%v", token.header["sub"])
        }

        return []byte(os.getenv("secret")), nil
    })

    log.printf("(middleware) token : %v", token)
    log.printf("(middleware) error : %v", err)

    if claims, ok := token.claims.(jwt.mapclaims); ok && token.valid {
        if float64(time.now().unix()) > claims["exp"].(float64) {
            panic(exception.newuserunauthorized(errors.new("user unauthorized").error()))
        }

        log.printf("(middleware) claims : %v", claims)
        log.printf("(middleware) ok : %v", ok)
        
        var db *sql.db

        tx, err := db.begin()
        
        log.printf("(middleware) tx : %v", tx)
        log.printf("(middleware) error : %v", err)
        
        query :=`
            select email from users 
            where email = ? 
            limit 1
        `
        log.printf("(middleware) query : %v", query)

        user, err := tx.querycontext(c.context(), query, claims["sub"])

        log.printf("(middleware) user  : %v", user)
        log.printf("(middleware) error : %v", err)
        

        if err != nil {
            panic(exception.newuserunauthorized(errors.new("user unauthorized").error()))
        }

        c.locals("user", user)
        c.next()
    }else {
        panic(exception.newuserunauthorized(errors.new("user unauthorized").error()))
    }

    return nil
}

Cette partie est le code du problème

var db *sql.db
tx, err := db.begin()   
log.printf("(middleware) tx : %v", tx) // no detect in terminal

Voici le résultat du journal

2023/02/12 10:00:04 (middleware) token : eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2NzYxNzEzOTIsInN1YiI6IkphZmFyQGdtYWlsLmNvbSJ9.6nn_IaNACHfe7flFMOXfj1ygZS-U_yrnU_Gvjn8xCp8
2023/02/12 10:00:04 (middleware) token : &{eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2NzYxNzEzOTIsInN1YiI6IkphZmFyQGdtYWlsLmNvbSJ9.6nn_IaNACHfe7flFMOXfj1ygZS-U_yrnU_Gvjn8xCp8 0xc0000a6780 map[alg:HS256 typ:JWT] map[exp:1.676171392e+09 sub:[email protected]] 6nn_IaNACHfe7flFMOXfj1ygZS-U_yrnU_Gvjn8xCp8 true}
2023/02/12 10:00:04 (middleware) error : <nil>
2023/02/12 10:00:04 (middleware) claims : map[exp:1.676171392e+09 sub:[email&#160;protected]]
2023/02/12 10:00:04 (middleware) ok : true

Alors, comment résoudre le problème d'accès à la base de données si différents packages sont utilisés ?

Solution de contournement

Vous devez transmettre le gestionnaire de base de données au middleware via l'enregistrement de la route.

Changez votre authmiddleware pour qu'il soit renvoyé par une fonction qui prend db *sql.db comme argument :

func newauthmiddleware(db *sql.db) fiber.handler {
    return func(c *fiber.ctx) error {
       // the rest of your function is here and has access to db
    }
}

Ensuite, vous devez appeler newauthmiddleware dans la fonction routeinit

func routeinit(app *fiber.app, usercontroller controller.usercontroller, db *sql.db) {
    app.get("/users", middleware.newauthmiddleware(db), usercontroller.findall)
    app.post("/login", usercontroller.login)
}

Passez ensuite la base de données à routeinit() dans la fonction principale

func main() {
    // ... as before

    route.RouteInit(app, userController, db)
}

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!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer