Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
En este tutorial, usará una marca de característica variante para administrar experiencias para distintos segmentos de usuario en una aplicación de ejemplo, Quote of the Day. Use la marca de característica variant creada en Use variant feature flags (Usar marcas de características variantes). Antes de continuar, asegúrese de crear la marca de característica variante denominada Greeting en el almacén de App Configuration.
Prerrequisitos
- Una cuenta de Azure con una suscripción activa. cree una de forma gratuita.
- Un almacén de configuración de aplicaciones, como se muestra en el tutorial para crear un almacén.
- Vaya a la versión 1.21 o posterior. Para obtener información sobre la instalación de Go, consulte la página Descargas de Go.
- Proveedor Go de Azure App Configuration v1.1.0 o posterior.
- Biblioteca go de administración de características v1.1.0 o posterior.
- Siga el tutorial Uso de marcas de características variantes y cree la marca de característica variante denominada Greeting.
Configuración de una aplicación web de Go Gin
Cree un directorio para el proyecto de Go y vaya a él:
mkdir quote-of-the-day cd quote-of-the-dayInicialice un nuevo módulo de Go:
go mod init quote-of-the-dayInstale los paquetes de Go necesarios:
go get github.com/gin-gonic/gin go get github.com/gin-contrib/sessions go get github.com/gin-contrib/sessions/cookie go get github.com/microsoft/Featuremanagement-Go/featuremanagement go get github.com/microsoft/Featuremanagement-Go/featuremanagement/providers/azappconfigCree un directorio de plantillas para las plantillas HTML y agregue los archivos HTML necesarios:
mkdir templatesAgregue los siguientes archivos de plantilla HTML desde el repositorio de GitHub y colóquelos en el
templatesdirectorio:-
index.html- La plantilla de página principal -
login.html- La plantilla de página de inicio de sesión
-
Cree un archivo denominado
appconfig.gocon el siguiente contenido. Puede conectarse a su App Configuration store utilizando Microsoft Entra ID (recomendado) o una cadena de conexión.package main import ( "context" "log" "os" "github.com/Azure/AppConfiguration-GoProvider/azureappconfiguration" "github.com/Azure/azure-sdk-for-go/sdk/azidentity" ) func loadAzureAppConfiguration(ctx context.Context) (*azureappconfiguration.AzureAppConfiguration, error) { // Get the endpoint from environment variable endpoint := os.Getenv("AZURE_APPCONFIG_ENDPOINT") if endpoint == "" { log.Fatal("AZURE_APPCONFIG_ENDPOINT environment variable is not set") } // Create a credential using DefaultAzureCredential credential, err := azidentity.NewDefaultAzureCredential(nil) if err != nil { log.Fatalf("Failed to create credential: %v", err) } // Set up authentication options with endpoint and credential authOptions := azureappconfiguration.AuthenticationOptions{ Endpoint: endpoint, Credential: credential, } // Set up options to enable feature flags options := &azureappconfiguration.Options{ FeatureFlagOptions: azureappconfiguration.FeatureFlagOptions{ Enabled: true, RefreshOptions: azureappconfiguration.RefreshOptions{ Enabled: true, }, }, } // Load configuration from Azure App Configuration appConfig, err := azureappconfiguration.Load(ctx, authOptions, options) if err != nil { log.Fatalf("Failed to load configuration: %v", err) } return appConfig, nil }
Uso de la marca de característica variant
Cree un archivo denominado
main.gocon el siguiente contenido:package main import ( "context" "fmt" "log" "net/http" "strings" "github.com/Azure/AppConfiguration-GoProvider/azureappconfiguration" "github.com/gin-contrib/sessions" "github.com/gin-contrib/sessions/cookie" "github.com/gin-gonic/gin" "github.com/microsoft/Featuremanagement-Go/featuremanagement" "github.com/microsoft/Featuremanagement-Go/featuremanagement/providers/azappconfig" ) type Quote struct { Message string `json:"message"` Author string `json:"author"` } type WebApp struct { featureManager *featuremanagement.FeatureManager appConfig *azureappconfiguration.AzureAppConfiguration quotes []Quote } func main() { // Load Azure App Configuration appConfig, err := loadAzureAppConfiguration(context.Background()) if err != nil { log.Fatalf("Error loading Azure App Configuration: %v", err) } // Create feature flag provider featureFlagProvider, err := azappconfig.NewFeatureFlagProvider(appConfig) if err != nil { log.Fatalf("Error creating feature flag provider: %v", err) } // Create feature manager featureManager, err := featuremanagement.NewFeatureManager(featureFlagProvider, nil) if err != nil { log.Fatalf("Error creating feature manager: %v", err) } // Initialize quotes quotes := []Quote{ { Message: "You cannot change what you are, only what you do.", Author: "Philip Pullman", }, } // Create web app app := &WebApp{ featureManager: featureManager, appConfig: appConfig, quotes: quotes, } // Setup Gin with default middleware (Logger and Recovery) r := gin.Default() // Start server if err := r.Run(":8080"); err != nil { log.Fatalf("Failed to start server: %v", err) } fmt.Println("Starting Quote of the Day server on http://localhost:8080") fmt.Println("Open http://localhost:8080 in your browser") fmt.Println() }Habilite la configuración y el refresco de banderas de características desde Azure App Configuration mediante el middleware.
// Existing code // ... ... func (app *WebApp) refreshMiddleware() gin.HandlerFunc { return func(c *gin.Context) { go func() { if err := app.appConfig.Refresh(context.Background()); err != nil { log.Printf("Error refreshing configuration: %v", err) } }() c.Next() } } // The rest of existing code //... ...Configure las rutas con el siguiente contenido:
// Existing code // ... ... func (app *WebApp) setupRoutes(r *gin.Engine) { // Setup sessions store := cookie.NewStore([]byte("secret-key-change-in-production")) store.Options(sessions.Options{ MaxAge: 3600, // 1 hour HttpOnly: true, Secure: false, // Set to true in production with HTTPS }) r.Use(sessions.Sessions("session", store)) r.Use(app.refreshMiddleware()) // Load HTML templates r.LoadHTMLGlob("templates/*.html") // Routes r.GET("/", app.homeHandler) r.GET("/login", app.loginPageHandler) r.POST("/login", app.loginHandler) r.GET("/logout", app.logoutHandler) } // Home page handler func (app *WebApp) homeHandler(c *gin.Context) { session := sessions.Default(c) username := session.Get("username") quote := app.quotes[0] var greetingMessage string var targetingContext featuremanagement.TargetingContext if username != nil { // Create targeting context for the user targetingContext = createTargetingContext(username.(string)) // Get the Greeting variant for the current user if variant, err := app.featureManager.GetVariant("Greeting", targetingContext); err != nil { log.Printf("Error getting Greeting variant: %v", err) } else if variant != nil && variant.ConfigurationValue != nil { // Extract the greeting message from the variant configuration if configValue, ok := variant.ConfigurationValue.(string); ok { greetingMessage = configValue } } } c.HTML(http.StatusOK, "index.html", gin.H{ "title": "Quote of the Day", "user": username, "greetingMessage": greetingMessage, "quote": quote, }) } func (app *WebApp) loginPageHandler(c *gin.Context) { c.HTML(http.StatusOK, "login.html", gin.H{ "title": "Login - Quote of the Day", }) } func (app *WebApp) loginHandler(c *gin.Context) { email := strings.TrimSpace(c.PostForm("email")) // Basic validation if email == "" { c.HTML(http.StatusOK, "login.html", gin.H{ "title": "Login - Quote of the Day", "error": "Email cannot be empty", }) return } if !strings.Contains(email, "@") { c.HTML(http.StatusOK, "login.html", gin.H{ "title": "Login - Quote of the Day", "error": "Please enter a valid email address", }) return } // Store email in session session := sessions.Default(c) session.Set("username", email) if err := session.Save(); err != nil { log.Printf("Error saving session: %v", err) } c.Redirect(http.StatusFound, "/") } func (app *WebApp) logoutHandler(c *gin.Context) { session := sessions.Default(c) session.Clear() if err := session.Save(); err != nil { log.Printf("Error saving session: %v", err) } c.Redirect(http.StatusFound, "/") } // Helper function to create TargetingContext func createTargetingContext(userID string) featuremanagement.TargetingContext { targetingContext := featuremanagement.TargetingContext{ UserID: userID, Groups: []string{}, } if strings.Contains(userID, "@") { parts := strings.Split(userID, "@") if len(parts) == 2 { domain := parts[1] targetingContext.Groups = append(targetingContext.Groups, domain) // Add domain as group } } return targetingContext } // The rest of existing code //... ...Actualice el
main.gocon el siguiente contenido:// Existing code // ... ... r := gin.Default() // Setup routes app.setupRoutes(r) // Start server if err := r.Run(":8080"); err != nil { log.Fatalf("Failed to start server: %v", err) } // The rest of existing code // ... ...
Compilación y ejecución de la aplicación
Establezca la variable de entorno para la autenticación y ejecute la aplicación:
go mod tidy go run .Abra el explorador web y vaya a
http://localhost:8080. Seleccione Iniciar sesión en la parte superior derecha para iniciar sesión como usera@contoso.com.
Una vez que haya iniciado sesión, verá un mensaje de saludo largo para usera@contoso.com.
Haga clic en Cerrar sesión e iniciar sesión como userb@contoso.com, verá el mensaje de saludo simple.
Nota:
Es importante que este tutorial use estos nombres exactamente. Siempre que la característica se haya configurado según lo previsto, los dos usuarios deben ver variantes diferentes.
Pasos siguientes
Para obtener más información sobre la administración de características en Go, continúe con los siguientes documentos: