App Configuration Server SDK for Go
App Configuration 服務提供 SDK,可與 Golang Web 和行動式應用程式、微服務及分散式環境整合。
必要條件
以下是使用 App Configuration service SDK for Go 的必要條件:
- Go 1.16 版或更新版本
整合伺服器 SDK for Go
已撤回 App Configuration Go SDK 的 v1.x.x。
App Configuration 服務提供 SDK,可與 Golang Web 和行動式應用程式、微服務及分散式環境整合。 您可以透過整合 App Configuration SDK,來評估內容及特性旗標的值。
-
使用
git
儲存庫中的下列程式碼來安裝 SDK。go get -u github.com/IBM/appconfiguration-go-sdk@latest
-
在 Golang 微服務或應用程式中,包含 SDK 模組:
import ( AppConfiguration "github.com/IBM/appconfiguration-go-sdk/lib" )
執行
go mod tidy
,以下載並安裝新的相依關係,並更新 Go 應用程式的go.mod
檔案。 -
起始設定 SDK 以使用 App Configuration 服務實例進行連接。
collectionId := "airlines-webapp" environmentId := "dev" appConfigClient := AppConfiguration.GetInstance() appConfigClient.Init("region", "guid", "apikey") appConfigClient.SetContext(collectionId, environmentId)
其中,
region
:建立 App Configuration 服務實體的區域名稱。 請參閱 此處 的支援地點清單。 例如:-us-south
,au-syd
等。guid
: App Configuration 服務的實例 ID。 請從 App Configuration 服務儀表板的服務認證區段取得它。apiKey
: App Configuration 服務的 ApiKey。 請從 App Configuration 服務儀表板的服務認證區段取得它。collectionId
: 在 App Configuration 服務實例中建立的集合 ID。environmentId
: 在 App Configuration 服務實例的「環境」區段下建立的環境 ID。
init()
和setContext()
是起始設定方法,只需要 使用appConfigClient
來啟動一次。 在起始設定之後,可以使用AppConfiguration.GetInstance()
跨模組取得appConfigClient
。
使用專用端點
設定 SDK,以使用只能透過 IBM Cloud 專用網路存取的專用端點來連接至 App Configuration 服務。
appConfigClient.UsePrivateEndpoint(true)
在 SDK 上呼叫 Init
函數之前,必須先完成此動作。
使用持續性快取進行配置的選項
為了讓您的應用程式及 SDK 即使在 App Configuration 服務關閉時間的罕見實務期間仍能繼續作業,在應用程式重新啟動時,您可以將 SDK 配置成使用持續性快取來運作。 SDK 使用持續性快取來儲存應用程式重新啟動時可用的 App Configuration 資料。
// 1. default (without persistent cache)
appConfiguration.SetContext(collectionId, environmentId)
// 2. with persistent cache
appConfiguration.SetContext(collectionId, environmentId, AppConfiguration.ContextOptions{
PersistentCacheDirectory: "/var/lib/docker/volumes/",
})
其中 persistentCacheDirectory
: 具有使用者讀取及寫入權之目錄的絕對路徑。 SDK 會在指定的目錄中建立 AppConfiguration.json
檔案,並用作持續性快取來儲存 App Configuration 服務資訊。
當啟用持續快取時,SDK 會在持續快取中保留前次已知的良好配置。 如果無法呼叫到 App Configuration 伺服器,則會將持續快取中的最新配置載入應用程式以繼續工作。
請確定在任何情況下都不會遺失或刪除快取檔。 例如,假設 Kubernetes Pod 重新啟動,且快取檔 (appconfiguration.json
) 儲存在 Pod 的暫時磁區中。 當 Pod 重新啟動時,kubernetes 會毀損 Pod 中的 ephermal 磁區,因此會刪除快取檔。 因此,請提供持續性目錄的正確絕對路徑,確定 SDK 所建立的快取檔一律儲存在持續性磁區中。
離線選項
SDK 也設計為提供配置,並執行特性旗標及內容評估,而不連接至 App Configuration 服務。
appConfiguration.SetContext(collectionId, environmentId, AppConfiguration.ContextOptions{
BootstrapFile: "saflights/flights.json",
LiveConfigUpdateEnabled: false,
})
其中,
-
BootstrapFile
:JSON 檔案的絕對路徑,包含配置詳細資料。 請務必提供適當的 JSON 檔案。 您可以使用 IBM Cloud App Configuration CLI 的ibmcloud ac export
指令來產生此檔案。 -
LiveConfigUpdateEnabled
: 從伺服器進行即時配置更新。 如果不得從伺服器提取新的配置值,請將此值設為false
。 預設值為啟用。
使用內容及特性相關 API 的範例
請參閱所列出的範例,以使用內容及特性相關 API。
取得單一特性
feature, err := appConfigClient.GetFeature("online-check-in")
if err == nil {
fmt.Println("Feature Name", feature.GetFeatureName())
fmt.Println("Feature Id", feature.GetFeatureID())
fmt.Println("Feature Type", feature.GetFeatureDataType())
if (feature.IsEnabled()) {
// feature flag is enabled
} else {
// feature flag is disabled
}
}
取得所有特性
features, err := appConfigClient.GetFeatures()
if err == nil {
feature := features["online-check-in"]
fmt.Println("Feature Name", feature.GetFeatureName())
fmt.Println("Feature Id", feature.GetFeatureID())
fmt.Println("Feature Type", feature.GetFeatureDataType())
fmt.Println("Is feature enabled?", feature.IsEnabled())
}
特性評估
您可以使用 feature.GetCurrentValue(entityId, entityAttributes)
方法來評估特性旗標的值。GetCurrentValue
會根據評估傳回其中一個「已啟用」、「已停用」或「已置換」值。
entityId := "john_doe"
entityAttributes := make(map[string]interface{})
entityAttributes["city"] = "Bangalore"
entityAttributes["country"] = "India"
featureVal := feature.GetCurrentValue(entityId, entityAttributes)
-
entityId
:entityId
是與將對其評估特性之「實體」相關的字串 ID。 例如,實體可能是在行動式裝置上執行的應用程式實例、在雲端上執行的微服務,或執行該微服務之基礎架構的元件。 若要讓任何實體與 App Configuration互動,它必須提供唯一實體 ID。 -
entityAttributes
:entityAttributes
是map[string]interface{}
類型的對映,由定義指定實體的屬性名稱及其值組成。 如果特性旗標未配置任何目標定義,則這是選用參數。 如果已配置目標,則必須提供entityAttributes
以進行規則評估。 屬性是用來定義區段的參數。 SDK 使用屬性值來判斷指定的實體是否滿足目標規則,並傳回適當的特性旗標值。
取得單一內容
property, err := appConfigClient.GetProperty("check-in-charges")
if err == nil {
fmt.Println("Property Name", property.GetPropertyName())
fmt.Println("Property Id", property.GetPropertyID())
fmt.Println("Property Type", property.GetPropertyDataType())
}
取得所有內容
properties, err := appConfigClient.GetProperties()
if err == nil {
property := properties["check-in-charges"]
fmt.Println("Property Name", property.GetPropertyName())
fmt.Println("Property Id", property.GetPropertyID())
fmt.Println("Property Type", property.GetPropertyDataType())
}
內容評估
您可以使用 property.GetCurrentValue(entityId, entityAttributes)
方法來評估內容的值。GetCurrentValue
會根據評估傳回預設內容值或其置換值。
entityId := "john_doe"
entityAttributes := make(map[string]interface{})
entityAttributes["city"] = "Bangalore"
entityAttributes["country"] = "India"
propertyVal := property.GetCurrentValue(entityId, entityAttributes)
-
entityId
:entityId
是與將對其評估內容的實體相關的字串 ID。 例如,實體可能是在行動式裝置上執行的應用程式實例、在雲端上執行的微服務,或執行該微服務之基礎架構的元件。 若要讓任何實體與 App Configuration互動,它必須提供唯一實體 ID。 -
entityAttributes
:entityAttributes
是map[string]interface{}
類型的對映,由定義指定實體的屬性名稱及其值組成。 如果內容未配置任何目標定義,則這是選用參數。 如果已配置目標,則必須提供entityAttributes
以進行規則評估。 屬性是用來定義區段的參數。 SDK 會使用屬性值來判斷指定的實體是否滿足目標規則,並傳回適當的內容值。
取得密鑰內容
secretPropertyObject, err := appConfiguration.GetSecret(propertyID, secretsManagerObject)
-
propertyID
:propertyID
是唯一字串 ID,使用此 ID 您將能夠提取內容,該內容提供提取密鑰所需的資料。 -
secretsManagerObject
:secretsManagerObject
是 Secrets Manager 變數或物件,將在密鑰內容評估期間用於取得密鑰。 如需如何建立 Secrets Manager 物件的相關資訊,請參閱 這裡。
評估密鑰內容
使用 secretPropertyObject.GetCurrentValue(entityId, entityAttributes)
方法來評估密鑰內容的值。GetCurrentValue
會根據評估傳回密鑰值。
entityId := "john_doe"
entityAttributes := make(map[string]interface{})
entityAttributes["city"] = "Bangalore"
entityAttributes["country"] = "India"
getSecretRes, detailedResponse, err := secretPropertyObject.GetCurrentValue(entityId, entityAttributes)
-
entityId
:entityId
是與將對其評估內容的實體相關的字串 ID。 例如,實體可能是在行動式裝置上執行的應用程式實例、在雲端上執行的微服務,或執行該微服務之基礎架構的元件。 若要讓任何實體與 App Configuration互動,它必須提供唯一實體 ID。 -
entityAttributes
:entityAttributes
是map[string]interface{}
類型的對映,由定義指定實體的屬性名稱及其值組成。 如果內容未配置任何目標定義,則這是選用參數。 如果已配置目標,則必須提供entityAttributes
以進行規則評估。 屬性是用來定義區段的參數。 SDK 會使用屬性值來判斷指定的實體是否滿足目標規則,並傳回適當的內容值。
如何從回應存取有效負載密碼資料
//make sure this import statement is added
import (sm "github.com/IBM/secrets-manager-go-sdk/secretsmanagerv1")
secret := getSecretRes.Resources[0].(*sm.SecretResource)
secretData := secret.SecretData.(map[string]interface{})
payload := secretData["payload"]
GetCurrentValue
將傳送這三個物件作為回應的一部分。
getSecretRes
: 這將提供 meta 資料和有效負載。detailedResponse
: 這將提供整個資料,其中包括 http 回應標頭資料、meta 資料及有效負載。err
: 如果要求無效或因某些原因而失敗,這會提供錯誤回應。
secretData["payload"]
會傳回 interface{}
,因此會根據您執行類型強制轉型所需的資料。
跨其他模組提取 appConfigClient
SDK 初始化之後,就可以跨其他模組取得 appConfigClient
,如下所示:
// **other modules**
import (
AppConfiguration "github.com/IBM/appconfiguration-go-sdk/lib"
)
appConfigClient := AppConfiguration.GetInstance()
feature, err := appConfigClient.GetFeature("online-check-in")
if (err == nil) {
enabled := feature.IsEnabled()
featureValue := feature.GetCurrentValue(entityId, entityAttributes)
}
支援的資料類型
您可以使用 App Configuration來配置特性旗標和內容,支援下列資料類型: 布林、數值、字串和 SecretRef。 「字串」資料類型可以是字串、JSON 或 YAML。 SDK 處理每一個格式,如表格中所示。
特性或內容值 | 資料類型 | 資料格式 | GetCurrentValue() 傳回的資料類型 |
輸出範例 |
---|---|---|---|---|
true |
BOOLEAN | 不適用 | bool |
true |
25 |
NUMERIC | 不適用 | float64 |
25 |
{ "secret_type": "kv", "id": "secret_id_data_here", "sm_instance_crn": "crn_data_added-here" } |
SECRETREF (此類型僅適用於內容) | 不適用 | map[string]interface{} |
{ "metadata": { "collection_type":"application/vnd.ibm.secrets-manager.secret+json", "collection_total": 1 }, "resources": [{"created_by": "iam-ServiceId-e4a2f0a4-3c76-4bef-b1f2-fbeae11c0f21", "creation_date": "2020-10-05T21:33:11Z", "crn": "crn:v1:bluemix:public:secrets-manager:us-south:a/a5ebf2570dcaedf18d7ed78e216c263a:f1bc94a6-64aa-4c55-b00f-f6cd70e4b2ce:secret:cb7a2502-8ede-47d6-b5b6-1b7af6b6f563", "description": "Extended description for this secret.", "expiration_date": "2021-01-01T00:00:00Z", "id": "cb7a2502-8ede-47d6-b5b6-1b7af6b6f563", "labels": ["dev","us-south"], "last_update_date": "2020-10-05T21:33:11Z", "name": "example-arbitrary-secret", "secret_data": {"payload": "secret-data"}, "secret_type": "arbitrary", "state": 1, "state_description": "Active", "versions_total": 1, "versions": [{"created_by": "iam-ServiceId-222b47ab-b08e-4619-b68f-8014a2c3acb8","creation_date": "2020-11-23T20:15:01Z","id": "50277266-d706-4b3e-badb-f07257f8f581","payload_available": true,"downloaded": true}],"locks_total": 2}] } Note: Along with the above data you will also provide the detailedResponse and error data. |
「字串文字」 | STRING | TEXT | string |
a string text |
{"firefox": { "name": "Firefox", "pref_url": "about:config" }} |
STRING | JSON | map[string]interface{} |
map[browsers:map[firefox:map[name:Firefox pref_url:about:config]]] |
men: - John Smith - Bill Jones women: - Mary Smith - Susan Williams |
STRING | YAML | map[string]interface{} |
map[men:[John Smith Bill Jones] women:[Mary Smith Susan Williams]] |
特性旗標
feature, err := appConfigClient.GetFeature("json-feature")
if err == nil {
feature.GetFeatureDataType() // STRING
feature.GetFeatureDataFormat() // JSON
// Example (traversing the returned map)
result := feature.GetCurrentValue(entityID, entityAttributes) // JSON value is returned as a Map
result.(map[string]interface{})["key"] // returns the value of the key
}
feature, err := appConfigClient.GetFeature("yaml-feature")
if err == nil {
feature.GetFeatureDataType() // STRING
feature.GetFeatureDataFormat() // YAML
// Example (traversing the returned map)
result := feature.GetCurrentValue(entityID, entityAttributes) // YAML value is returned as a Map
result.(map[string]interface{})["key"] // returns the value of the key
}
內容
property, err := appConfigClient.GetProperty("json-property")
if err == nil {
property.GetPropertyDataType() // STRING
property.GetPropertyDataFormat() // JSON
// Example (traversing the returned map)
result := property.GetCurrentValue(entityID, entityAttributes) // JSON value is returned as a Map
result.(map[string]interface{})["key"] // returns the value of the key
}
property, err := appConfigClient.GetProperty("yaml-property")
if err == nil {
property.GetPropertyDataType() // STRING
property.GetPropertyDataFormat() // YAML
// Example (traversing the returned map)
result := property.GetCurrentValue(entityID, entityAttributes) // YAML value is returned as a Map
result.(map[string]interface{})["key"] // returns the value of the key
}
接聽內容及特性變更
若要接聽資料變更,請在應用程式中新增下列程式碼:
appConfigClient.RegisterConfigurationUpdateListener(func () {
// **add your code**
// To find the effect of any configuration changes, you can call the feature or property related methods
// feature, err := appConfigClient.GetFeature("json-feature")
// newValue := feature.GetCurrentValue(entityID, entityAttributes)
})
提取最新資料
appConfigClient.FetchConfigurations()