Evitar conflitos de recursos FHIR usando ETags

Nesta página, explicamos como usar tags de entidade (ETags) para gerenciamento de simultaneidade com recursos FHIR na API Cloud Healthcare. As ETags ajudam a evitar a perda de dados e melhorar o desempenho do aplicativo, ativando o controle de simultaneidade otimista e o armazenamento em cache do lado do cliente.

Entender as ETags

Uma ETag serve como um identificador exclusivo do estado atual de um recurso FHIR no servidor, semelhante a um número de versão. Sempre que um recurso FHIR é criado ou modificado, um novo valor de ETag é gerado.

Você pode usar ETags para garantir a integridade dos dados e otimizar a performance nas seguintes situações:

  • Para garantir o controle de simultaneidade otimista: quando você inclui uma ETag em uma solicitação para modificar um recurso FHIR, a API Cloud Healthcare verifica se a ETag corresponde à versão mais recente do recurso FHIR no servidor. Isso ajuda a evitar que um cliente substitua acidentalmente as mudanças feitas por outro cliente, também chamado de conflito de gravação ou "problema de atualização perdida".

  • Envio de solicitações condicionais: as ETags permitem que os clientes enviem solicitações condicionais somente quando condições específicas são atendidas. Isso otimiza a recuperação de dados e reduz o tráfego de rede desnecessário. Por exemplo, é possível enviar solicitações condicionais usando os seguintes cabeçalhos HTTP:

    • If-Match: a solicitação só terá sucesso se a ETag fornecida corresponder à ETag atual no servidor. Isso garante que você está atualizando a versão esperada do recurso FHIR.
    • If-None-Match: a solicitação só terá sucesso se a ETag fornecida não corresponder à ETag atual no servidor. Isso permite saber se a versão armazenada em cache local de um recurso ainda está atualizada, reduzindo a necessidade de buscar o recurso completo do servidor a cada vez. Isso é comumente usado para armazenamento em cache eficiente.

As ETags do FHIR usam validação fraca, o que significa que elas podem não ser idênticas em diferentes instâncias do servidor, mas ainda rastreiam as mudanças de recursos.

Receber uma ETag

Os exemplos a seguir mostram como conseguir o ETag de um recurso FHIR.

A ETag é incluída no cabeçalho de resposta HTTP completo quando você recebe o conteúdo de um recurso FHIR. A ETag corresponde ao Meta.versionId no recurso FHIR.

Antes de usar os dados da solicitação, faça as substituições a seguir:

  • PROJECT_ID: o ID do projeto Google Cloud
  • LOCATION: o local do conjunto de dados;
  • DATASET_ID: o conjunto de dados pai do armazenamento de FHIR
  • FHIR_STORE_ID: o ID de armazenamento de FHIR
  • FHIR_RESOURCE_TYPE: o tipo de recurso FHIR
  • FHIR_RESOURCE_ID: o ID do recurso FHIR

curl

Use o método fhir.read. A flag -verbose retorna os cabeçalhos HTTP na resposta, que contêm a 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"

A resposta contém o seguinte:

< etag: W/"ETAG_VALUE"

PowerShell

Use o método fhir.read. A flag -Headers retorna os cabeçalhos HTTP na resposta, que contêm a 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

A resposta contém o seguinte:

ETag                   {W/"ETAG_VALUE"}

Gerenciar a simultaneidade ao atualizar um recurso FHIR

Os exemplos a seguir mostram como incluir uma ETag ao atualizar um recurso FHIR.

As amostras usam If-Match, que tem o seguinte comportamento:

  • Se a ETag corresponder à ETag atual do recurso FHIR no servidor, a atualização será bem-sucedida e o servidor gerará uma nova ETag para o recurso atualizado. Isso garante que você está atualizando a versão esperada do recurso FHIR.

  • Se a ETag não corresponder, a atualização vai falhar com um erro 412 Precondition Failed, indicando que outro cliente modificou o recurso desde que a ETag original foi buscada. Isso evita a perda de dados por substituições acidentais.

Antes de usar os dados da solicitação, faça as substituições a seguir:

  • ETAG_VALUE: o valor da ETag do recurso FHIR
  • PROJECT_ID: o ID do projeto Google Cloud
  • LOCATION: o local do conjunto de dados;
  • DATASET_ID: o conjunto de dados pai do armazenamento de FHIR
  • FHIR_STORE_ID: o ID de armazenamento de FHIR
  • FHIR_RESOURCE_TYPE: o tipo de recurso FHIR
  • FHIR_RESOURCE_ID: o ID do recurso FHIR

curl

Use o método 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"

A resposta contém o recurso FHIR atualizado.

PowerShell

Use o método 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

A resposta contém o recurso FHIR atualizado.

Implementar o armazenamento em cache do lado do cliente

Você pode usar ETags para implementar o armazenamento em cache do lado do cliente, o que acelera a recuperação de dados e contribui para uma experiência do usuário mais suave e responsiva.

Para recuperar um recurso FHIR armazenado em cache anteriormente, inclua a ETag armazenada em cache no cabeçalho If-None-Match, que tem o seguinte comportamento:

  • Se as ETags corresponderem, o servidor vai responder com 304 Not Modified, e o cliente vai usar a cópia em cache. Isso economiza largura de banda e reduz a carga do servidor.

  • Se as ETags não corresponderem, o servidor vai enviar o recurso FHIR atualizado e a nova ETag, permitindo que o cliente atualize o cache.

Os exemplos a seguir mostram como acessar o conteúdo de um recurso FHIR usando uma ETag que corresponde à ETag no servidor.

Antes de usar os dados da solicitação, faça as substituições a seguir:

  • ETAG_VALUE: o valor da ETag do recurso FHIR
  • PROJECT_ID: o ID do projeto Google Cloud
  • LOCATION: o local do conjunto de dados;
  • DATASET_ID: o conjunto de dados pai do armazenamento de FHIR
  • FHIR_STORE_ID: o ID de armazenamento de FHIR
  • FHIR_RESOURCE_TYPE: o tipo de recurso FHIR
  • FHIR_RESOURCE_ID: o ID do recurso FHIR

curl

Use o método fhir.read. A flag -verbose retorna os cabeçalhos HTTP na resposta. Caso contrário, nenhuma resposta é retornada.

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"

A resposta contém um código de status 304 Not Modified.

PowerShell

Use o método fhir.read. A flag -Headers retorna os cabeçalhos HTTP na resposta. Caso contrário, nenhuma resposta será retornada.

$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

A resposta contém um código de status 304 Not Modified.