IBM Cloud Docs
App Configuration Server SDK for Go

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,來評估內容及特性旗標的值。

  1. 使用 git 儲存庫中的下列程式碼來安裝 SDK。

    go get -u github.com/IBM/appconfiguration-go-sdk@latest
    
  2. 在 Golang 微服務或應用程式中,包含 SDK 模組:

    import (
       AppConfiguration "github.com/IBM/appconfiguration-go-sdk/lib"
    )
    

    執行 go mod tidy,以下載並安裝新的相依關係,並更新 Go 應用程式的 go.mod 檔案。

  3. 起始設定 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: entityAttributesmap[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: entityAttributesmap[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: entityAttributesmap[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()