ETag를 사용하여 FHIR 리소스 충돌 방지

이 페이지에서는 Cloud Healthcare API에서 FHIR 리소스와의 동시성 관리를 위해 항목 태그(ETag)를 사용하는 방법을 설명합니다. ETag는 최적의 동시성 제어와 클라이언트 측 캐싱을 사용 설정하여 데이터 손실을 방지하고 애플리케이션 성능을 향상시켜 줍니다.

ETag 이해하기

ETag는 버전 번호와 비슷하게 서버에서 FHIR 리소스의 현재 상태에 대한 고유 식별자로 사용됩니다. 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를 가져오는 방법을 보여줍니다.

ETag는 FHIR 리소스의 콘텐츠를 가져올 때 전체 HTTP 응답 헤더에 포함됩니다. 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 플래그는 응답에서 ETag가 포함된 HTTP 헤더를 반환합니다.

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 플래그는 응답에서 ETag가 포함된 HTTP 헤더를 반환합니다.

$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 상태 코드가 포함됩니다.