mirror of
https://github.com/Unleash/unleash.git
synced 2025-02-09 00:18:00 +01:00
Go tutorial 🐿️ (#8904)
And examples 😄
---------
Co-authored-by: melindafekete <melinda.fekete@getunleash.io>
Co-authored-by: Nnenna Ndukwe <nnenna.s.ndukwe@gmail.com>
This commit is contained in:
parent
abafa84ea5
commit
3afcf690de
BIN
website/docs/feature-flag-tutorials/golang/diagram.png
Normal file
BIN
website/docs/feature-flag-tutorials/golang/diagram.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 52 KiB |
300
website/docs/feature-flag-tutorials/golang/golang-examples.md
Normal file
300
website/docs/feature-flag-tutorials/golang/golang-examples.md
Normal file
@ -0,0 +1,300 @@
|
|||||||
|
---
|
||||||
|
title: Go feature flag examples
|
||||||
|
slug: /feature-flag-tutorials/golang/examples
|
||||||
|
---
|
||||||
|
|
||||||
|
In our [Go feature flag tutorial](/feature-flag-tutorials/go), we implemented a simple feature flag that could be turned on and off. This document will walk you through other examples of what can be achieved using feature flags in Go.
|
||||||
|
|
||||||
|
We built many features into Unleash, our open-source feature flag platform, to address the complexities of releasing code.
|
||||||
|
|
||||||
|
## Canary Deployments in Go
|
||||||
|
|
||||||
|
### What is a canary deployment?
|
||||||
|
|
||||||
|
Canary deployments are a foundational approach for deploying new software versions with high confidence and low risk by exposing the new version to a limited audience. Canary releases are a way to test and release code in different environments for a subset of your audience, which determines which features or versions of the platform people have access to.
|
||||||
|
|
||||||
|
### Why use canary deployments?
|
||||||
|
|
||||||
|
Canary deployments are a safer and more gradual way to make changes in software development. They help find any abnormalities and align with the agile process for faster releases and quick reversions.
|
||||||
|
|
||||||
|
### How to do canary deployments with a feature flag in Go?
|
||||||
|
|
||||||
|
Feature flags provide the same benefits as canary deployments but with more granular control:
|
||||||
|
|
||||||
|
- Precisely target specific user segments for feature rollouts.
|
||||||
|
- Maintain session consistency (stickiness) if needed.
|
||||||
|
- Test multiple features independently on different user groups simultaneously.
|
||||||
|
- With feature flags, you can separate feature releases from deployments.
|
||||||
|
|
||||||
|
Often, canary deployments are managed at the load balancer level while feature flags act at the application level. In some instances, rolling out groups of features together behind a feature flag can serve the purpose of a canary deployment.
|
||||||
|
|
||||||
|
### Configure strategy constraints for canary deployments
|
||||||
|
|
||||||
|
Let's update our existing gradual rollout strategy using Go to add [environment-based constraints](/reference/activation-strategies#constraints):
|
||||||
|
|
||||||
|
```go
|
||||||
|
payload := map[string]interface{}{
|
||||||
|
"name": "flexibleRollout",
|
||||||
|
"disabled": false,
|
||||||
|
"constraints": []map[string]interface{}{
|
||||||
|
{
|
||||||
|
"values": []string{"production"},
|
||||||
|
"inverted": false,
|
||||||
|
"operator": "NOT_IN",
|
||||||
|
"contextName": "environment",
|
||||||
|
"caseInsensitive": false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"variants": []interface{}{},
|
||||||
|
"parameters": map[string]interface{}{
|
||||||
|
"groupId": "delete_survey_flag",
|
||||||
|
"rollout": "50",
|
||||||
|
"stickiness": "sessionId",
|
||||||
|
},
|
||||||
|
"segments": []interface{}{},
|
||||||
|
}
|
||||||
|
|
||||||
|
jsonData, err := json.Marshal(payload)
|
||||||
|
|
||||||
|
url := fmt.Sprintf("%s/api/admin/projects/%s/features/%s/environments/%s/strategies/%s",
|
||||||
|
unleashURL, projectID, featureName, environment, strategyID)
|
||||||
|
|
||||||
|
req, err := http.NewRequest("PUT", url, bytes.NewBuffer(jsonData))
|
||||||
|
|
||||||
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
req.Header.Set("Authorization", apiKey)
|
||||||
|
|
||||||
|
client := &http.Client{}
|
||||||
|
resp, err := client.Do(req)
|
||||||
|
defer resp.Body.Close()
|
||||||
|
```
|
||||||
|
|
||||||
|
## Server-side A/B Testing in Go
|
||||||
|
|
||||||
|
A/B testing allows you to test multiple versions of a feature with different user groups. In Go, we can implement this using strategy variants. Here's how to update a strategy to enable A/B testing for 50% of users:
|
||||||
|
|
||||||
|
```go
|
||||||
|
payload := map[string]interface{}{
|
||||||
|
"name": "flexibleRollout",
|
||||||
|
"title": "",
|
||||||
|
"constraints": []interface{}{},
|
||||||
|
"parameters": map[string]interface{}{
|
||||||
|
"rollout": "50",
|
||||||
|
"stickiness": "default",
|
||||||
|
"groupId": "",
|
||||||
|
},
|
||||||
|
"variants": []interface{}{},
|
||||||
|
"segments": []interface{}{},
|
||||||
|
"disabled": false,
|
||||||
|
}
|
||||||
|
|
||||||
|
jsonData, err := json.Marshal(payload)
|
||||||
|
|
||||||
|
url := fmt.Sprintf("%s/api/admin/projects/%s/features/%s/environments/%s/strategies/%s",
|
||||||
|
unleashURL, projectID, featureName, environment, strategyID)
|
||||||
|
|
||||||
|
req, err := http.NewRequest("PUT", url, bytes.NewBuffer(jsonData))
|
||||||
|
|
||||||
|
|
||||||
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
req.Header.Set("Authorization", apiKey)
|
||||||
|
|
||||||
|
client := &http.Client{}
|
||||||
|
resp, err := client.Do(req)
|
||||||
|
defer resp.Body.Close()
|
||||||
|
```
|
||||||
|
|
||||||
|
## Feature Flag Analytics and Reporting in Go
|
||||||
|
|
||||||
|
Shipping code is one thing, but monitoring your applications is another aspect of managing code. For example, you could use feature flag analytics to monitor performance metrics or track user behavior.
|
||||||
|
|
||||||
|
### Enable impression data events in Go
|
||||||
|
|
||||||
|
Let's walk through how to enable impression data using Go's HTTP client:
|
||||||
|
|
||||||
|
```go
|
||||||
|
payload := []map[string]interface{}{
|
||||||
|
{
|
||||||
|
"op": "replace",
|
||||||
|
"path": "/impressionData",
|
||||||
|
"value": true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
jsonData, err := json.Marshal(payload)
|
||||||
|
|
||||||
|
|
||||||
|
url := fmt.Sprintf("%s/api/admin/projects/%s/features/%s",
|
||||||
|
unleashURL, projectID, featureName)
|
||||||
|
|
||||||
|
req, err := http.NewRequest("PATCH", url, bytes.NewBuffer(jsonData))
|
||||||
|
|
||||||
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
req.Header.Set("Authorization", apiKey)
|
||||||
|
|
||||||
|
client := &http.Client{}
|
||||||
|
resp, err := client.Do(req)
|
||||||
|
defer resp.Body.Close()
|
||||||
|
```
|
||||||
|
|
||||||
|
## Application Metrics and Monitoring for Go apps
|
||||||
|
|
||||||
|
In Go applications, you can implement metrics collection using the Unleash client SDK. Here's an example of how to track metrics for your feature flags:
|
||||||
|
|
||||||
|
```go
|
||||||
|
type MetricsData struct {
|
||||||
|
AppName string `json:"appName"`
|
||||||
|
InstanceID string `json:"instanceId"`
|
||||||
|
Bucket map[string]ToggleStats `json:"bucket"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ToggleStats struct {
|
||||||
|
Yes int `json:"yes"`
|
||||||
|
No int `json:"no"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func fetchMetrics(unleashURL, featureName, apiKey string) error {
|
||||||
|
url := fmt.Sprintf("%s/api/admin/metrics/feature-toggles/%s", unleashURL, featureName)
|
||||||
|
|
||||||
|
req, err := http.NewRequest("GET", url, nil)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error creating request: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
req.Header.Set("Authorization", apiKey)
|
||||||
|
|
||||||
|
client := &http.Client{
|
||||||
|
Timeout: 10 * time.Second,
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error making request: %v", err)
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
var metricsData MetricsData
|
||||||
|
if err := json.NewDecoder(resp.Body).Decode(&metricsData); err != nil {
|
||||||
|
return fmt.Errorf("error decoding response: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process metrics data
|
||||||
|
fmt.Printf("Metrics for %s: %+v\n", featureName, metricsData)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Feature Flag Audit Logs in Go
|
||||||
|
|
||||||
|
Implementing audit logging in your Go application helps track changes to feature flags over time. Here's how to retrieve and process audit logs:
|
||||||
|
|
||||||
|
```go
|
||||||
|
func getAuditLogs(unleashURL, featureName, apiKey string) error {
|
||||||
|
url := fmt.Sprintf("%s/api/admin/events/%s", unleashURL, featureName)
|
||||||
|
|
||||||
|
req, err := http.NewRequest("GET", url, nil)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error creating request: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
req.Header.Add("Accept", "application/json")
|
||||||
|
req.Header.Add("Authorization", apiKey)
|
||||||
|
|
||||||
|
client := &http.Client{}
|
||||||
|
resp, err := client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error making request: %v", err)
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
body, err := io.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error reading response: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println(string(body))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Flag Automation and Workflow Integration for Go Apps
|
||||||
|
|
||||||
|
An advanced use case for using feature flags at scale is automating them as part of your development workflow.
|
||||||
|
|
||||||
|
It's common for teams to have a development phase, then QA/testing, and then a production release. Our [Unleash Jira plugin](/reference/integrations/jira-cloud-plugin-installation) can connect to your Jira server or cloud to create feature flags automatically during the project phases.
|
||||||
|
|
||||||
|
As your code progresses through development and Jira tickets are updated, the relevant flag can turn on in a development environment. The next stage could be Canary deployments for testing with certain groups, like a QA team or beta users. The flag could be automatically turned on in QA and/or rolled out to target audiences in production.
|
||||||
|
|
||||||
|
Here's how this can be done via our API:
|
||||||
|
|
||||||
|
1. Enable a flag.
|
||||||
|
|
||||||
|
```go
|
||||||
|
url := fmt.Sprintf("%s/api/admin/projects/%s/features/%s/environments/%s/on",
|
||||||
|
unleashURL, projectID, featureName, environment)
|
||||||
|
|
||||||
|
req, err := http.NewRequest("POST", url, nil)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error creating request: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
req.Header.Add("Accept", "application/json")
|
||||||
|
req.Header.Add("Authorization", apiKey)
|
||||||
|
|
||||||
|
client := &http.Client{}
|
||||||
|
resp, err := client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error making request: %v", err)
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
```
|
||||||
|
|
||||||
|
Review our [API docs on flag enablement](/reference/api/unleash/toggle-feature-environment-on).
|
||||||
|
|
||||||
|
2. Update a flag.
|
||||||
|
|
||||||
|
```go
|
||||||
|
url := fmt.Sprintf("%s/api/admin/projects/%s/features/%s",
|
||||||
|
unleashURL, projectID, featureName)
|
||||||
|
|
||||||
|
payload := FeatureUpdate{
|
||||||
|
Description: "Controls disabling of the comments section in case of an incident",
|
||||||
|
Type: "kill-switch",
|
||||||
|
Stale: true,
|
||||||
|
Archived: true,
|
||||||
|
ImpressionData: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
jsonPayload, err := json.Marshal(payload)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error marshaling payload: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err := http.NewRequest("PUT", url, bytes.NewBuffer(jsonPayload))
|
||||||
|
req.Header.Add("Accept", "application/json")
|
||||||
|
req.Header.Add("Authorization", apiKey)
|
||||||
|
req.Header.Add("Content-Type", "application/json")
|
||||||
|
```
|
||||||
|
|
||||||
|
Review our [API docs on updating feature flags](/reference/api/unleash/update-feature).
|
||||||
|
|
||||||
|
3. Archive a flag.
|
||||||
|
|
||||||
|
```go
|
||||||
|
url := fmt.Sprintf("%s/api/admin/projects/%s/features/%s",
|
||||||
|
unleashURL, projectID, featureName)
|
||||||
|
|
||||||
|
req, err := http.NewRequest("DELETE", url, nil)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error creating request: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
req.Header.Add("Authorization", apiKey)
|
||||||
|
|
||||||
|
client := &http.Client{}
|
||||||
|
resp, err := client.Do(req)
|
||||||
|
```
|
||||||
|
|
||||||
|
Review [API docs on archiving flags](/reference/api/unleash/archive-feature).
|
||||||
|
|
||||||
|
Learn more about different use cases in our [Go SDK documentation](/reference/sdks/go).
|
@ -0,0 +1,281 @@
|
|||||||
|
---
|
||||||
|
title: How to Implement Feature Flags in Go
|
||||||
|
description: "How to use Unleash feature flags with Go."
|
||||||
|
slug: /feature-flag-tutorials/go
|
||||||
|
---
|
||||||
|
|
||||||
|
import VideoContent from '@site/src/components/VideoContent.jsx';
|
||||||
|
|
||||||
|
Hello! In this tutorial we'll show you how to add feature flags to your Go app, using [Unleash](https://www.getunleash.io/) and the official [Unleash Go SDK](/reference/sdks/go). With Unleash, an open-source feature flag service, you can add feature flags to your application to release new features faster.
|
||||||
|
|
||||||
|
In this tutorial, we'll get information about a country from the [REST Countries API](https://restcountries.com/), and its [GraphQL counterpart](https://countries.trevorblades.com/) using Go. We'll use feature flags to decide whether to call the REST or the GraphQL version of the API.
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
For this tutorial, you'll need the following:
|
||||||
|
|
||||||
|
- Go v1.16+
|
||||||
|
- Git
|
||||||
|
- Docker and Docker Compose
|
||||||
|
- Go Modules, to manage your dependencies
|
||||||
|
|
||||||
|
![architecture diagram for our implementation](./diagram.png)
|
||||||
|
|
||||||
|
The Unleash Server is a **Feature Flag Control Service**, which manages your feature flags and lets you retrieve flag data. Unleash has a UI for creating and managing projects and feature flags. You can perform the same actions straight from your CLI or server-side app using the [Unleash API](/reference/api/unleash).
|
||||||
|
|
||||||
|
## Best practices for back-end apps with Unleash
|
||||||
|
|
||||||
|
Go is a back-end language, so there are special considerations to plan around when implementing feature flags.
|
||||||
|
|
||||||
|
Most importantly, you must:
|
||||||
|
|
||||||
|
- Limit feature flag payloads for scalability, security, and efficiency.
|
||||||
|
- Use graceful degradation where possible to improve the resiliency of your architecture.
|
||||||
|
|
||||||
|
![A gradual rollout form can allow you to customize your flag strategy.](/img/go-example-rollout.png)
|
||||||
|
|
||||||
|
For a complete list of architectural guidelines, including caching strategies, see our [best practices for building and scaling feature flag systems](/topics/feature-flags/feature-flag-best-practices).
|
||||||
|
|
||||||
|
## Install a local feature flag provider
|
||||||
|
|
||||||
|
In this section, we'll install Unleash, run the instance locally, log in, and create a feature flag. If you prefer, you can use other tools instead of Unleash, but you'll need to update the code accordingly.
|
||||||
|
|
||||||
|
Use Git to clone the Unleash repository and Docker to build and run it. Open a terminal window and run the following commands:
|
||||||
|
|
||||||
|
```
|
||||||
|
git clone https://github.com/unleash/unleash.git
|
||||||
|
cd unleash
|
||||||
|
docker compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
You will now have Unleash installed onto your machine and running in the background. You can access this instance in your web browser at [http://localhost:4242](http://localhost:4242).
|
||||||
|
|
||||||
|
Log in to the platform using these credentials:
|
||||||
|
|
||||||
|
```
|
||||||
|
Username: admin
|
||||||
|
Password: unleash4all
|
||||||
|
```
|
||||||
|
|
||||||
|
Click **New feature flag** to create a new feature flag.
|
||||||
|
|
||||||
|
![Create a new feature flag](/img/go-new-feature-flag.png)
|
||||||
|
|
||||||
|
Call it `graphql-api` and enable it in the `development` environment.
|
||||||
|
|
||||||
|
![A feature flag called `graphql-api` is now enabled in development.](/img/go-enable-development.png)
|
||||||
|
|
||||||
|
Everything's now set up on the Unleash side. Let's go to the code now.
|
||||||
|
|
||||||
|
## Grab country information from the REST Countries API
|
||||||
|
|
||||||
|
We'll use the standard `net/http` package to make our HTTP requests and the Unleash SDK to connect to your local Unleash instance and retrieve your feature flag.
|
||||||
|
|
||||||
|
Open a new tab in your terminal, and create a new folder (outside of the unleash folder).
|
||||||
|
|
||||||
|
```sh
|
||||||
|
mkdir unleash-go
|
||||||
|
cd unleash-go
|
||||||
|
go mod init unleash-demo
|
||||||
|
```
|
||||||
|
|
||||||
|
Install dependencies:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
go get github.com/Unleash/unleash-client-go/v4
|
||||||
|
```
|
||||||
|
|
||||||
|
Next, let's make sure our setup is working. Make a call to the REST API to retrieve information about a country using its country code. Create a file named `main.go`:
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Country struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Capital string `json:"capital"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
resp, err := http.Get("https://restcountries.com/v2/alpha/no")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
body, _ := io.ReadAll(resp.Body)
|
||||||
|
var country Country
|
||||||
|
json.Unmarshal(body, &country)
|
||||||
|
|
||||||
|
fmt.Printf("Country: %s, Capital: %s\n", country.Name, country.Capital)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Run the code:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
go run main.go
|
||||||
|
```
|
||||||
|
|
||||||
|
You should see `Country: Norway, Capital: Oslo` in your terminal.
|
||||||
|
|
||||||
|
## Add the GraphQL endpoint
|
||||||
|
|
||||||
|
The point of this tutorial is to mimic a real-world scenario where, based on a boolean feature flag, you would migrate from a REST API to a GraphQL one. So far, we've just used REST.
|
||||||
|
|
||||||
|
Let's create a static feature flag, for now, just to test that we can call both versions successfully. Update `main.go`:
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Country struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Capital string `json:"capital"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// Define a static feature flag
|
||||||
|
isGraphQL := true
|
||||||
|
|
||||||
|
var country Country
|
||||||
|
if isGraphQL {
|
||||||
|
// Call the GraphQL API
|
||||||
|
query := `{"query": "query { country(code: \"NO\") { name capital } }"}`
|
||||||
|
req, err := http.NewRequest("POST", "https://countries.trevorblades.com/", bytes.NewBuffer([]byte(query)))
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
|
||||||
|
client := &http.Client{}
|
||||||
|
resp, err := client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
body, _ := io.ReadAll(resp.Body)
|
||||||
|
var response struct {
|
||||||
|
Data struct {
|
||||||
|
Country Country `json:"country"`
|
||||||
|
} `json:"data"`
|
||||||
|
}
|
||||||
|
json.Unmarshal(body, &response)
|
||||||
|
|
||||||
|
country = response.Data.Country
|
||||||
|
fmt.Println("Hello GraphQL")
|
||||||
|
} else {
|
||||||
|
// Call the REST API
|
||||||
|
resp, err := http.Get("https://restcountries.com/v2/alpha/no")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
body, _ := io.ReadAll(resp.Body)
|
||||||
|
var countries []Country
|
||||||
|
json.Unmarshal(body, &countries)
|
||||||
|
country = countries[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("Country: %s, Capital: %s\n", country.Name, country.Capital)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Run the code again:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
go run main.go
|
||||||
|
```
|
||||||
|
|
||||||
|
You should see `Hello GraphQL`, followed by `Country: Norway, Capital: Oslo` in your terminal.
|
||||||
|
|
||||||
|
## 5. Add Unleash to your Go app
|
||||||
|
|
||||||
|
Now, let's connect our project to Unleash so that you can toggle that feature flag at runtime. If you wanted to, you could also do a [gradual rollout](/feature-flag-tutorials/use-cases/gradual-rollout) or use the flag for [A/B testing](/feature-flag-tutorials/use-cases/a-b-testing).
|
||||||
|
|
||||||
|
You'll need 2 things:
|
||||||
|
|
||||||
|
- The URL of your Unleash instance's API. It's `http://localhost:4242/api/` for your local version.
|
||||||
|
- The API token we created on our Unleash instance, feel free to create another one if you can't find it.
|
||||||
|
|
||||||
|
With these 2, you can initialize your Unleash client as follows:
|
||||||
|
|
||||||
|
```go
|
||||||
|
unleash.Initialize(
|
||||||
|
unleash.WithUrl("http://localhost:4242/api/"),
|
||||||
|
unleash.WithAppName("country_go"),
|
||||||
|
unleash.WithCustomHeaders(http.Header{"Authorization": {"YOUR_API_KEY"}}),
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
Now, let's add our client to our project, grab the feature flag from Unleash, and update our conditional statement. Don't forget to also update the config with your API key:
|
||||||
|
|
||||||
|
```diff
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
+ "github.com/Unleash/unleash-client-go/v4"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ... rest of the types ...
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
+ // Initialize Unleash client
|
||||||
|
+ unleash.Initialize(
|
||||||
|
+ unleash.WithUrl("http://localhost:4242/api/"),
|
||||||
|
+ unleash.WithAppName("country_go"),
|
||||||
|
+ unleash.WithCustomHeaders(http.Header{"Authorization": {"YOUR_API_KEY"}}),
|
||||||
|
+ )
|
||||||
|
+
|
||||||
|
+ unleash.WaitForReady()
|
||||||
|
|
||||||
|
+ isGraphQL := unleash.IsEnabled("graphql-api")
|
||||||
|
- // Define a static feature flag
|
||||||
|
- isGraphQL := true
|
||||||
|
|
||||||
|
// ... rest of the code ...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
See additional use cases in our [Server-Side SDK with Go](https://docs.getunleash.io/reference/sdks/go) documentation.
|
||||||
|
|
||||||
|
## 6. Verify the toggle experience
|
||||||
|
|
||||||
|
Now that we've connected our project to Unleash and grabbed our feature flag, we can verify that if you disable that flag in your development environment, you stop seeing the `Hello GraphQL` message and only get the country information from the REST API.
|
||||||
|
|
||||||
|
> **Note:** An update to a feature flag may take 30 seconds to propagate.
|
||||||
|
|
||||||
|
## Conclusion
|
||||||
|
|
||||||
|
All done! Now you know how to add feature flags with Unleash in Go. You've learned how to:
|
||||||
|
|
||||||
|
- Toggle between a REST and a GraphQL endpoint based on a feature flag
|
||||||
|
- Install Unleash and create/enable a feature flag
|
||||||
|
- Grab the value of a feature flag with the Go SDK
|
||||||
|
|
||||||
|
Feel free to have a look at our [Go Examples page](/feature-flag-tutorials/golang/examples) for more.
|
||||||
|
|
||||||
|
Thank you
|
@ -223,6 +223,21 @@ const sidebars: SidebarsConfig = {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
type: 'category',
|
||||||
|
label: 'Go',
|
||||||
|
link: {
|
||||||
|
type: 'doc',
|
||||||
|
id: 'feature-flag-tutorials/golang/implementing-feature-flags-golang',
|
||||||
|
},
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
type: 'doc',
|
||||||
|
label: 'Go Examples',
|
||||||
|
id: 'feature-flag-tutorials/golang/golang-examples',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
type: 'category',
|
type: 'category',
|
||||||
label: '.NET',
|
label: '.NET',
|
||||||
|
BIN
website/static/img/go-enable-development.png
Normal file
BIN
website/static/img/go-enable-development.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 515 KiB |
BIN
website/static/img/go-example-rollout.png
Normal file
BIN
website/static/img/go-example-rollout.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 389 KiB |
BIN
website/static/img/go-example-strategy.png
Normal file
BIN
website/static/img/go-example-strategy.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 245 KiB |
BIN
website/static/img/go-new-feature-flag.png
Normal file
BIN
website/static/img/go-new-feature-flag.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 245 KiB |
Loading…
Reference in New Issue
Block a user