使用 ETag 避免 FHIR 資源衝突

本頁面說明如何使用實體標記 (ETag),在 Cloud Healthcare API 中對 FHIR 資源進行並行管理。ETag 可啟用開放式並行控制和用戶端快取,有助於防止資料遺失及提升應用程式效能。

瞭解 ETag

ETag 可做為伺服器上 FHIR 資源目前狀態的專屬 ID,類似於版本號碼。每次建立或修改 FHIR 資源時,系統都會產生新的 ETag 值。

在下列情況中,您可以使用 ETag 確保資料完整性並提升效能:

  • 為確保樂觀並行控制:在修改 FHIR 資源的要求中加入 ETag 時,Cloud Healthcare API 會驗證 ETag 是否與伺服器上最新版本的 FHIR 資源相符。這有助於防止某個用戶端意外覆寫另一個用戶端所做的變更,也就是所謂的寫入-寫入衝突或「更新遺失問題」。

  • 傳送條件式要求:ETag 可讓用戶端僅在符合特定條件時,有條件地傳送要求。這項做法可最佳化資料擷取作業,並減少不必要的網路流量。舉例來說,您可以使用下列 HTTP 標頭傳送條件要求:

    • If-Match:只有在提供的 ETag 與伺服器上的目前 ETag 相符時,要求才會成功。確保您更新的是預期的 FHIR 資源版本。
    • If-None-Match:只有在提供的 ETag 與伺服器上的目前 ETag 不符時,要求才會成功。這可讓您瞭解資源的本機快取版本是否仍為最新版本,減少每次從伺服器擷取完整資源的需求。這通常用於有效率的快取。

FHIR ETag 使用弱驗證,因此在不同伺服器執行個體中可能不盡相同,但仍可有效追蹤資源變更。

取得 ETag

下列範例說明如何取得 FHIR 資源的 ETag。

當您取得 FHIR 資源的內容時,系統會在完整的 HTTP 回應標頭中加入 ETag。ETag 與 FHIR 資源中的 Meta.versionId 相符。

使用任何要求資料之前,請先替換以下項目:

  • PROJECT_ID:您的 Google Cloud 專案 ID
  • LOCATION:資料集位置
  • DATASET_ID:FHIR 儲存庫的父項資料集
  • FHIR_STORE_ID:FHIR 儲存庫 ID
  • FHIR_RESOURCE_TYPE:FHIR 資源類型
  • FHIR_RESOURCE_ID:FHIR 資源 ID

curl

請使用 fhir.read 方法。-verbose 旗標會傳回回應中的 HTTP 標頭,其中包含 ETag。

curl -X GET \
    -verbose \
    -H "Authorization: Bearer $(gcloud auth print-access-token)" \
    "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/FHIR_RESOURCE_TYPE/FHIR_RESOURCE_ID"

回應包含下列項目:

< etag: W/"ETAG_VALUE"

PowerShell

請使用 fhir.read 方法。-Headers 旗標會傳回回應中的 HTTP 標頭,其中包含 ETag。

$cred = gcloud auth print-access-token
$headers = @{ "Authorization" = "Bearer $cred" }

Invoke-WebRequest `
    -Method GET `
    -Headers $headers `
    -Uri "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/FHIR_RESOURCE_TYPE/FHIR_RESOURCE_ID" | Select-Object -Expand Headers

回應包含下列項目:

ETag                   {W/"ETAG_VALUE"}

更新 FHIR 資源時管理並行作業

下列範例說明如何更新 FHIR 資源時加入 ETag。

這些範例使用 If-Match,其行為如下:

  • 如果 ETag 與伺服器上 FHIR 資源的目前 ETag 相符,更新作業就會成功,且伺服器會為更新後的資源產生新的 ETag。確保更新的 FHIR 資源版本符合預期。

  • 如果 ETag 不相符,更新就會失敗並顯示 412 Precondition Failed 錯誤,表示自擷取原始 ETag 後,有其他用戶端修改了資源。防止資料因意外覆寫而遺失。

使用任何要求資料之前,請先替換以下項目:

  • ETAG_VALUE:FHIR 資源的 ETag 值
  • PROJECT_ID:您的 Google Cloud 專案 ID
  • LOCATION:資料集位置
  • DATASET_ID:FHIR 儲存庫的父項資料集
  • FHIR_STORE_ID:FHIR 儲存庫 ID
  • FHIR_RESOURCE_TYPE:FHIR 資源類型
  • FHIR_RESOURCE_ID:FHIR 資源 ID

curl

請使用 fhir.update 方法。

curl -X PUT \
    -H "If-Match: W/\"ETAG_VALUE\"" \
    -H "Content-Type: application/json; charset=utf-8" \
    -H "Authorization: Bearer $(gcloud auth print-access-token)" \
    -d @request.json \
    "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/FHIR_RESOURCE_TYPE/FHIR_RESOURCE_ID"

回覆包含更新後的 FHIR 資源。

PowerShell

請使用 fhir.update 方法。

$cred = gcloud auth print-access-token
$etag = W/\"ETAG_VALUE\""
$headers = @{
  "Authorization" = "Bearer $cred"
  "If-Match"      = "$etag"}

Invoke-WebRequest `
    -Method PUT `
    -Headers $headers `
    -InFile request.json `
    -Uri "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/FHIR_RESOURCE_TYPE/FHIR_RESOURCE_ID" | Select-Object -Expand Content

回覆包含更新後的 FHIR 資源。

實作用戶端快取

您可以使用 ETag 實作用戶端快取,加快資料擷取速度,進而提供更流暢、更快速的回應式使用者體驗。

如要擷取先前快取的 FHIR 資源,您可以在 If-None-Match 標頭中加入快取的 ETag,這會產生下列行為:

  • 如果 ETag 相符,伺服器會傳回 304 Not Modified,而用戶端會使用快取副本。這樣可以節省頻寬並減輕伺服器負載。

  • 如果 ETag 不相符,伺服器會傳送更新後的 FHIR 資源和新的 ETag,讓用戶端重新整理快取。

下列範例說明如何使用與伺服器上 ETag 相符的 ETag,取得 FHIR 資源的內容。

使用任何要求資料之前,請先替換以下項目:

  • ETAG_VALUE:FHIR 資源的 ETag 值
  • PROJECT_ID:您的 Google Cloud 專案 ID
  • LOCATION:資料集位置
  • DATASET_ID:FHIR 儲存庫的父項資料集
  • FHIR_STORE_ID:FHIR 儲存庫 ID
  • FHIR_RESOURCE_TYPE:FHIR 資源類型
  • FHIR_RESOURCE_ID:FHIR 資源 ID

curl

請使用 fhir.read 方法。-verbose 旗標會在回應中傳回 HTTP 標頭,否則不會傳回任何回應。

curl -X GET \
    -H "If-None-Match: W/\"ETAG_VALUE\"" \
    -v \
    -H "Authorization: Bearer $(gcloud auth print-access-token)" \
    "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/FHIR_RESOURCE_TYPE/FHIR_RESOURCE_ID"

回應會包含 304 Not Modified 狀態碼。

PowerShell

請使用 fhir.read 方法。-Headers 旗標會在回應中傳回 HTTP 標頭,否則不會傳回任何回應。

$cred = gcloud auth print-access-token
$etag = W/\"ETAG_VALUE\""
$headers = @{
"Authorization" = "Bearer $cred"
  "If-None-Match"      = "$etag"}

Invoke-WebRequest `
    -Method GET `
    -Headers $headers `
    -Uri "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/FHIR_RESOURCE_TYPE/FHIR_RESOURCE_ID" | Select-Object -Expand Headers

回應會包含 304 Not Modified 狀態碼。