|
| 1 | +--- |
| 2 | +title: "Tutorial: Use dynamic configuration in a Gin web app" |
| 3 | +titleSuffix: Azure App Configuration |
| 4 | +description: In this quickstart, learn how to dynamically update configuration data for Gin web applications |
| 5 | +author: linglingye |
| 6 | +ms.service: azure-app-configuration |
| 7 | +ms.devlang: golang |
| 8 | +ms.topic: quickstart |
| 9 | +ms.date: 05/27/2025 |
| 10 | +ms.author: linglingye |
| 11 | +ms.custom: devx-track-go |
| 12 | +--- |
| 13 | + |
| 14 | +# Tutorial: Use dynamic configuration in a Gin web app |
| 15 | + |
| 16 | +This tutorial shows how you can implement dynamic configuration updates in a Gin web application using Azure App Configuration. It builds on the web app introduced in the previous quickstart. |
| 17 | + |
| 18 | +## Prerequisites |
| 19 | + |
| 20 | +Finish the quickstart: [Create a Gin web app with Azure App Configuration](./quickstart-go-web-app.md) |
| 21 | + |
| 22 | +## Reload data from App Configuration |
| 23 | + |
| 24 | +1. Open the file *`appconfig.go`*. Inside the `loadAzureAppConfiguration` function, update the `options` to enable refresh. Go provider will reload the entire configuration whenever it detects a change in any of the selected key-values. For more information about monitoring configuration changes, see [Best practices for configuration refresh](./howto-best-practices.md#configuration-refresh). |
| 25 | + |
| 26 | + ```golang |
| 27 | + options := &azureappconfiguration.Options{ |
| 28 | + Selectors: []azureappconfiguration.Selector{ |
| 29 | + { |
| 30 | + KeyFilter: "Config.*", |
| 31 | + }, |
| 32 | + }, |
| 33 | + TrimKeyPrefixes: []string{"Config."}, |
| 34 | + RefreshOptions: azureappconfiguration.KeyValueRefreshOptions{ |
| 35 | + Enabled: true, |
| 36 | + }, |
| 37 | + } |
| 38 | + ``` |
| 39 | + |
| 40 | + > [!TIP] |
| 41 | + > You can set the `Interval` property of the `RefreshOptions` to specify the minimum time between configuration refreshes. In this example, you use the default value of 30 seconds. Adjust to a higher value if you need to reduce the number of requests made to your App Configuration store. |
| 42 | + |
| 43 | +2. Update your `main.go` file to register a callback function for configuration updates: |
| 44 | + |
| 45 | + ```golang |
| 46 | + // Existing code |
| 47 | + // ... ... |
| 48 | + var config Config |
| 49 | + if err := provider.Unmarshal(&config, nil); err != nil { |
| 50 | + log.Fatalf("Failed to unmarshal configuration: %v", err) |
| 51 | + } |
| 52 | +
|
| 53 | + // Register refresh callback |
| 54 | + provider.OnRefreshSuccess(func() { |
| 55 | + // Re-unmarshal the configuration |
| 56 | + err := provider.Unmarshal(&config, nil) |
| 57 | + if err != nil { |
| 58 | + log.Printf("Failed to unmarshal updated configuration: %s", err) |
| 59 | + return |
| 60 | + } |
| 61 | + }) |
| 62 | + ``` |
| 63 | + |
| 64 | +3. Add a configuration refresh middleware. Update *`main.go`* with the following code. |
| 65 | + |
| 66 | + ```golang |
| 67 | + func configRefreshMiddleware(provider *azureappconfiguration.AzureAppConfiguration) gin.HandlerFunc { |
| 68 | + return func(c *gin.Context) { |
| 69 | + // Start refresh in a goroutine to avoid blocking the request |
| 70 | + go func() { |
| 71 | + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) |
| 72 | + defer cancel() |
| 73 | +
|
| 74 | + if err := provider.Refresh(ctx); err != nil { |
| 75 | + log.Printf("Error refreshing configuration: %s", err) |
| 76 | + } |
| 77 | + }() |
| 78 | +
|
| 79 | + c.Next() |
| 80 | + } |
| 81 | + } |
| 82 | + ``` |
| 83 | + |
| 84 | +4. Use the configuration refresh middleware: |
| 85 | + |
| 86 | + ```golang |
| 87 | + // Existing code |
| 88 | + // ... ... |
| 89 | + router := gin.Default() |
| 90 | +
|
| 91 | + // Use the configuration refresh middleware |
| 92 | + router.Use(configRefreshMiddleware(provider)) |
| 93 | +
|
| 94 | + // The rest of existing code |
| 95 | + //... ... |
| 96 | + ``` |
| 97 | + |
| 98 | +## Request-driven configuration refresh |
| 99 | + |
| 100 | +The configuration refresh is triggered by the incoming requests to your web app. No refresh will occur if your app is idle. When your app is active, the configuration refresh middleware monitors the selected key-values you configured in `azureappconfiguration.Options`. The middleware is triggered upon every incoming request to your app. However, the middleware will only send requests to check the value in App Configuration when the refresh interval you set has passed. |
| 101 | + |
| 102 | +- If a request to App Configuration for change detection fails, your app will continue to use the cached configuration. New attempts to check for changes will be made periodically while there are new incoming requests to your app. |
| 103 | +- The configuration refresh happens asynchronously to the processing of your app's incoming requests. It will not block or slow down the incoming request that triggered the refresh. The request that triggered the refresh may not get the updated configuration values, but later requests will get new configuration values. |
| 104 | +- To ensure the middleware is triggered, use the configuration refresh middleware as early as appropriate in your request pipeline so another middleware won't skip it in your app. |
| 105 | + |
| 106 | +## Run the web application |
| 107 | + |
| 108 | +Now that you've set up dynamic configuration refresh, let's test it to see it in action. |
| 109 | + |
| 110 | +1. Run the application. |
| 111 | + |
| 112 | + ```bash |
| 113 | + go run main.go |
| 114 | + ``` |
| 115 | + |
| 116 | +2. Open a web browser and navigate to `http://localhost:8080` to access your application. The web page looks like this: |
| 117 | + |
| 118 | + :::image type="content" source="./media/quickstarts/gin-app-refresh-before.png" alt-text="Screenshot of the gin web app refresh before."::: |
| 119 | + |
| 120 | +3. Navigate to your App Configuration store and update the value of the `Config.Message` key. |
| 121 | + |
| 122 | + | Key | Value | Content type | |
| 123 | + |------------------------|----------------------------------------|--------------------| |
| 124 | + | *Config.Message* | *Hello from Azure App Configuration - now with live updates!* | Leave empty | |
| 125 | + |
| 126 | +4. After refreshing the browser a few times, you'll see the updated content once the ConfigMap is updated in 30 seconds. |
| 127 | +
|
| 128 | + :::image type="content" source="./media/quickstarts/gin-app-refresh-after.png" alt-text="Screenshot of the gin web app refresh after."::: |
| 129 | +
|
| 130 | +
|
| 131 | +## Clean up resources |
| 132 | +
|
| 133 | +[!INCLUDE [azure-app-configuration-cleanup](../../includes/azure-app-configuration-cleanup.md)] |
0 commit comments