FHIR 번들을 사용하여 FHIR 리소스 관리

이 페이지에서는 FHIR 리소스에서 수행할 FHIR 리소스 및 작업의 컬렉션인 FHIR 번들을 실행하여 FHIR 리소스를 관리하는 방법을 설명합니다.

ExecuteBundle 메서드는 FHIR 표준 배치/트랜잭션 상호작용(DSTU2, STU3, R4) 및 기록 작업을 구현합니다.

FHIR 번들

FHIR 번들에는 관찰 또는 환자 같은 리소스에 대한 만들기, 업데이트, 삭제 등의 작업을 나타내는 항목 배열이 포함됩니다. 번들 리소스에서 요소에 대한 자세한 설명을 참조하세요.

FHIR 번들을 실행할 때 번들 유형에 따라 번들의 작업 수행 방법이 결정됩니다. 사용 가능한 번들 유형은 다음과 같습니다.

  • batch: 작업을 여러 독립적인 요청으로 수행합니다.
  • transaction: 작업을 서로 의존되는 여러 요청으로 실행합니다.
  • history: 리소스 기록에 항목을 삽입합니다.

예를 들어 트랜잭션 번들에 환자 리소스 및 관찰 리소스 만들기가 포함된다고 가정해보세요. 환자 리소스 만들기 요청이 실패하면 관찰 리소스가 생성되지 않습니다.

번들 유형이 batch인 경우 작업이 실패하면 Cloud Healthcare API가 번들에서 나머지 작업을 실행합니다. 번들 유형이 transaction인 경우 작업이 실패하면 Cloud Healthcare API가 작업 실행을 중지하고 트랜잭션을 롤백합니다.

기록 번들

기록 번들은 동기화와 같은 백업 및 복원 사용 사례를 지원하는 FHIR 표준의 커스텀 확장 프로그램입니다. 기록 번들을 사용하여 FHIR 리소스 기록에 리소스 버전을 삽입하거나 대체할 수 있습니다. Resource-purge 메서드를 사용하여 리소스 버전만 삭제할 수 있습니다. history 번들은 번들당 항목 100개로 제한되는 단일 트랜잭션으로 실행됩니다. history 번들의 리소스 버전에 FHIR 스토어의 최신 버전보다 높은 타임스탬프가 있으면 그에 따라 최신 버전이 업데이트됩니다. history 번들이 성공적으로 삽입되면 빈 응답이 반환되고 그렇지 않으면 실패를 설명하는 OperationOutcome이 반환됩니다.

기록 번들 지원은 기본적으로 사용 설정되지 않습니다. FHIR 스토어 관리자는 FHIR 스토어 구성에서 enableHistoryModificationstrue로 설정해야 합니다. FHIR 스토어 구성에서 disableResourceVersioningtrue로 설정된 경우 기록 번들을 사용할 수 없습니다.

기록 번들은 fhir.history 메서드에서 반환되는 형식과 동일한 형식으로 제공됩니다. 유효하려면 각 번들 항목에 리소스 ID, 수정 타임스탬프, 상태가 필요합니다. 또한 모든 항목은 동일한 리소스 ID를 가져야 합니다. 리소스 ID에는 resource.id 필드 또는 request.url 필드가 제공됩니다. 필드가 제공되면 제공된 리소스 ID는 동일합니다. 리소스 타임스탬프는 리소스의 meta.lastUpdated 필드 또는 response.lastModified 필드와 함께 제공됩니다.

번들 실행에 대한 권한 부여

번들을 실행하려면 datasets.fhirStores.fhir.executeBundle 권한 역할이 필요합니다. 이 권한을 부여하려면 healthcare.fhirResourceReader 역할을 사용하세요. 이 권한을 부여하는 단계는 정책 수정을 참조하세요.

기록 번들을 실행하려면 datasets.fhirStores.fhir.import 권한 역할도 필요합니다.

Cloud Healthcare API는 번들의 각 작업에 대한 권한을 확인합니다. healthcare.fhirResources.create 권한만 있고 healthcare.fhirResources.update 권한이 없는 경우 healthcare.fhirResources.create 작업을 포함하는 번들만 실행할 수 있습니다.

번들 실행

FHIR 번들을 실행하려면 projects.locations.datasets.fhirStores.fhir.executeBundle 메서드를 사용합니다.

다음 샘플에서 BUNDLE.json은 JSON으로 인코딩된 FHIR 번들의 경로 및 파일 이름입니다. 요청 본문에 번들을 포함할 수도 있습니다.

다음 샘플 번들은 환자 리소스를 만들고 다른 환자 리소스를 삭제합니다.

{
  "resourceType": "Bundle",
  "id": "bundle-transaction",
  "meta": {
    "lastUpdated": "2018-03-11T11:22:16Z"
  },
  "type": "transaction",
  "entry": [
    {
      "resource": {
        "resourceType": "Patient",
        "name": [
          {
            "family": "Smith",
            "given": [
              "Darcy"
            ]
          }
        ],
        "gender": "female",
        "address": [
          {
            "line": [
              "123 Main St."
            ],
            "city": "Anycity",
            "state": "CA",
            "postalCode": "12345"
          }
        ]
      },
      "request": {
        "method": "POST",
        "url": "Patient"
      }
    },
    {
      "request": {
        "method": "DELETE",
        "url": "Patient/1234567890"
      }
    }
  ]
}

다음 샘플은 번들 실행 방법을 보여줍니다.

curl

번들을 실행하려면 POST 요청을 수행하고 다음 정보를 지정합니다.

  • 상위 데이터 세트와 FHIR 저장소의 이름 및 위치
  • 로컬 머신의 번들 파일 위치
  • 액세스 토큰

다음 샘플은 curl을 사용하는 POST 요청을 보여줍니다.

curl -X POST \
    -H "Content-Type: application/fhir+json; charset=utf-8" \
    -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
    --data @BUNDLE_FILE.json \
    "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir"

개별 작업의 결과와 관계없이 배치 번들을 실행한 후 서버는 batch-response 유형 Bundle 리소스의 JSON 인코딩 표현을 반환합니다. Bundle 리소스는 요청에 입력한 내용과 해당 입력을 처리한 결과를 하나의 항목으로 포함합니다. 이 결과에는 성공 결과와 오류 결과가 혼합되어 있을 수 있습니다

트랜잭션 번들이 성공하면 서버는 요청에 입력한 내용과 성공적인 작업 결과를 하나의 항목으로 포함한 transaction-response 유형 Bundle 리소스의 JSON 인코딩 표현을 반환합니다.

트랜잭션 번들을 실행하는 동안 오류가 발생하면 응답 본문에 번들이 포함되지 않습니다. 대신 오류가 발생한 이유를 설명하는 JSON 인코딩 OperationOutcome 리소스가 포함됩니다. 롤백한 성공적인 작업은 응답에 보고되지 않습니다.

다음 샘플 번들은 위 예시를 성공적으로 실행한 출력입니다. 첫 번째 항목은 환자 만들기 작업의 성공을 나타내고 새 리소스의 ID를 포함합니다. 두 번째 항목은 삭제 작업의 성공을 나타냅니다.

{
  "entry": [
    {
      "response": {
        "location": projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/RESOURCE/RESOURCE_ID,
        "status": "201 Created"
      }
    },
    {
      "response": {
        "status": "200 OK"
      }
    }
  ],
  "resourceType": "Bundle",
  "type": "transaction-response"
}

PowerShell

번들을 실행하려면 POST 요청을 수행하고 다음 정보를 지정합니다.

  • 상위 데이터 세트와 FHIR 저장소의 이름 및 위치
  • 로컬 머신의 번들 파일 위치
  • 액세스 토큰

다음 샘플은 Windows PowerShell을 사용한 POST 요청을 보여줍니다.

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

Invoke-RestMethod `
  -Method Post `
  -Headers $headers `
  -ContentType: "application/fhir+json" `
  -InFile BUNDLE_FILE.json `
  -Uri "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir" | ConvertTo-Json

개별 작업의 결과와 관계없이 배치 번들을 실행한 후 서버는 batch-response 유형 Bundle 리소스의 JSON 인코딩 표현을 반환합니다. Bundle 리소스는 요청에 입력한 내용과 해당 입력을 처리한 결과를 하나의 항목으로 포함합니다. 이 결과에는 성공 결과와 오류 결과가 혼합되어 있을 수 있습니다

트랜잭션 번들이 성공하면 서버는 요청에 입력한 내용과 성공적인 작업 결과를 하나의 항목으로 포함한 transaction-response 유형 Bundle 리소스의 JSON 인코딩 표현을 반환합니다.

트랜잭션 번들을 실행하는 동안 오류가 발생하면 응답 본문에 번들이 포함되지 않습니다. 대신 오류가 발생한 이유를 설명하는 JSON 인코딩 OperationOutcome 리소스가 포함됩니다. 롤백한 성공적인 작업은 응답에 보고되지 않습니다.

다음 샘플 번들은 위 예시를 성공적으로 실행한 출력입니다. 첫 번째 항목은 환자 만들기 작업의 성공을 나타내고 새 리소스의 ID를 포함합니다. 두 번째 항목은 삭제 작업의 성공을 나타냅니다.

{
  "entry": [
    {
      "response": {
        "etag": "ETAG",
        "lastModified": "2020-08-03T04:12:47.312669+00:00",
        "location": "projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/RESOURCE/RESOURCE_ID",
        "status": "201 Created"
      }
    },
    {
      "response": {
        "etag": "ETAG",
        "lastModified": "2020-08-03T04:12:47.312669+00:00",
        "status": "200 OK"
      }
    }
  ],
  "resourceType": "Bundle",
  "type": "transaction-response"
}

Go

import (
	"bytes"
	"context"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"

	healthcare "google.golang.org/api/healthcare/v1"
)

// fhirExecuteBundle executes an FHIR bundle.
func fhirExecuteBundle(w io.Writer, projectID, location, datasetID, fhirStoreID string) error {
	ctx := context.Background()

	healthcareService, err := healthcare.NewService(ctx)
	if err != nil {
		return fmt.Errorf("healthcare.NewService: %w", err)
	}

	fhirService := healthcareService.Projects.Locations.Datasets.FhirStores.Fhir

	payload := map[string]interface{}{
		"resourceType": "Bundle",
		"type":         "transaction",
		"entry": []map[string]interface{}{
			{
				"resource": map[string]interface{}{
					"resourceType": "Patient",
					"active":       true,
				},
				"request": map[string]interface{}{
					"method": "POST",
					"url":    "Patient",
				},
			},
		},
	}
	jsonPayload, err := json.Marshal(payload)
	if err != nil {
		return fmt.Errorf("json.Encode: %w", err)
	}

	parent := fmt.Sprintf("projects/%s/locations/%s/datasets/%s/fhirStores/%s", projectID, location, datasetID, fhirStoreID)

	call := fhirService.ExecuteBundle(parent, bytes.NewReader(jsonPayload))
	call.Header().Set("Content-Type", "application/fhir+json;charset=utf-8")
	resp, err := call.Do()
	if err != nil {
		return fmt.Errorf("ExecuteBundle: %w", err)
	}
	defer resp.Body.Close()

	respBytes, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return fmt.Errorf("could not read response: %w", err)
	}

	if resp.StatusCode > 299 {
		return fmt.Errorf("Create: status %d %s: %s", resp.StatusCode, resp.Status, respBytes)
	}
	fmt.Fprintf(w, "%s", respBytes)

	return nil
}

Java

import com.google.api.client.http.HttpRequestInitializer;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.gson.GsonFactory;
import com.google.api.services.healthcare.v1.CloudHealthcare;
import com.google.api.services.healthcare.v1.CloudHealthcareScopes;
import com.google.auth.http.HttpCredentialsAdapter;
import com.google.auth.oauth2.GoogleCredentials;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.Collections;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.methods.RequestBuilder;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClients;

public class FhirStoreExecuteBundle {
  private static final String FHIR_NAME = "projects/%s/locations/%s/datasets/%s/fhirStores/%s";
  private static final JsonFactory JSON_FACTORY = new GsonFactory();
  private static final NetHttpTransport HTTP_TRANSPORT = new NetHttpTransport();

  public static void fhirStoreExecuteBundle(String fhirStoreName, String data)
      throws IOException, URISyntaxException {
    // String fhirStoreName =
    //    String.format(
    //        FHIR_NAME, "your-project-id", "your-region-id", "your-dataset-id", "your-fhir-id");
    // String data = "{\"resourceType\": \"Bundle\",\"type\": \"batch\",\"entry\": []}"

    // Initialize the client, which will be used to interact with the service.
    CloudHealthcare client = createClient();
    HttpClient httpClient = HttpClients.createDefault();
    String baseUri = String.format("%sv1/%s/fhir", client.getRootUrl(), fhirStoreName);
    URIBuilder uriBuilder = new URIBuilder(baseUri).setParameter("access_token", getAccessToken());
    StringEntity requestEntity = new StringEntity(data);

    HttpUriRequest request =
        RequestBuilder.post()
            .setUri(uriBuilder.build())
            .setEntity(requestEntity)
            .addHeader("Content-Type", "application/fhir+json")
            .addHeader("Accept-Charset", "utf-8")
            .addHeader("Accept", "application/fhir+json; charset=utf-8")
            .build();

    // Execute the request and process the results.
    HttpResponse response = httpClient.execute(request);
    HttpEntity responseEntity = response.getEntity();
    if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
      System.err.print(
          String.format(
              "Exception executing FHIR bundle: %s\n", response.getStatusLine().toString()));
      responseEntity.writeTo(System.err);
      throw new RuntimeException();
    }
    System.out.print("FHIR bundle executed: ");
    responseEntity.writeTo(System.out);
  }

  private static CloudHealthcare createClient() throws IOException {
    // Use Application Default Credentials (ADC) to authenticate the requests
    // For more information see https://cloud.google.com/docs/authentication/production
    GoogleCredentials credential =
        GoogleCredentials.getApplicationDefault()
            .createScoped(Collections.singleton(CloudHealthcareScopes.CLOUD_PLATFORM));

    // Create a HttpRequestInitializer, which will provide a baseline configuration to all requests.
    HttpRequestInitializer requestInitializer =
        request -> {
          new HttpCredentialsAdapter(credential).initialize(request);
          request.setConnectTimeout(60000); // 1 minute connect timeout
          request.setReadTimeout(60000); // 1 minute read timeout
        };

    // Build the client for interacting with the service.
    return new CloudHealthcare.Builder(HTTP_TRANSPORT, JSON_FACTORY, requestInitializer)
        .setApplicationName("your-application-name")
        .build();
  }

  private static String getAccessToken() throws IOException {
    GoogleCredentials credential =
        GoogleCredentials.getApplicationDefault()
            .createScoped(Collections.singleton(CloudHealthcareScopes.CLOUD_PLATFORM));

    return credential.refreshAccessToken().getTokenValue();
  }
}

Node.js

샘플 번들 파일은 코드 샘플의 GitHub 저장소에서 사용할 수 있습니다.

const google = require('@googleapis/healthcare');
const healthcare = google.healthcare({
  version: 'v1',
  auth: new google.auth.GoogleAuth({
    scopes: ['https://www.googleapis.com/auth/cloud-platform'],
  }),
  headers: {'Content-Type': 'application/fhir+json'},
});
const fs = require('fs');

async function executeFhirBundle() {
  // TODO(developer): uncomment these lines before running the sample
  // const cloudRegion = 'us-central1';
  // const projectId = 'adjective-noun-123';
  // const datasetId = 'my-dataset';
  // const fhirStoreId = 'my-fhir-store';
  // const bundleFile = 'bundle.json';
  const parent = `projects/${projectId}/locations/${cloudRegion}/datasets/${datasetId}/fhirStores/${fhirStoreId}`;

  const bundle = JSON.parse(fs.readFileSync(bundleFile));

  const request = {parent, requestBody: bundle};
  const resource =
    await healthcare.projects.locations.datasets.fhirStores.fhir.executeBundle(
      request
    );
  console.log('FHIR bundle executed');
  console.log(resource.data);
}

executeFhirBundle();

Python

샘플 번들 파일은 코드 샘플의 GitHub 저장소에서 사용할 수 있습니다.

def execute_bundle(
    project_id,
    location,
    dataset_id,
    fhir_store_id,
    bundle,
):
    """Executes the operations in the given bundle.

    See https://github.com/GoogleCloudPlatform/python-docs-samples/tree/main/healthcare/api-client/v1/fhir
    before running the sample."""
    # Imports Python's built-in "os" module
    import os

    # Imports the google.auth.transport.requests transport
    from google.auth.transport import requests

    # Imports a module to allow authentication using a service account
    from google.oauth2 import service_account

    # Gets credentials from the environment.
    credentials = service_account.Credentials.from_service_account_file(
        os.environ["GOOGLE_APPLICATION_CREDENTIALS"]
    )
    scoped_credentials = credentials.with_scopes(
        ["https://www.googleapis.com/auth/cloud-platform"]
    )
    # Creates a requests Session object with the credentials.
    session = requests.AuthorizedSession(scoped_credentials)

    # URL to the Cloud Healthcare API endpoint and version
    base_url = "https://healthcare.googleapis.com/v1"

    # TODO(developer): Uncomment these lines and replace with your values.
    # project_id = 'my-project'  # replace with your GCP project ID
    # location = 'us-central1'  # replace with the parent dataset's location
    # dataset_id = 'my-dataset'  # replace with the parent dataset's ID
    # fhir_store_id = 'my-fhir-store' # replace with the FHIR store ID
    # bundle = 'bundle.json'  # replace with the bundle file
    url = f"{base_url}/projects/{project_id}/locations/{location}"

    resource_path = "{}/datasets/{}/fhirStores/{}/fhir".format(
        url, dataset_id, fhir_store_id
    )

    headers = {"Content-Type": "application/fhir+json;charset=utf-8"}

    with open(bundle) as bundle_file:
        bundle_file_content = bundle_file.read()

    response = session.post(resource_path, headers=headers, data=bundle_file_content)
    response.raise_for_status()

    resource = response.json()

    print(f"Executed bundle from file: {bundle}")
    print(json.dumps(resource, indent=2))

    return resource

PATCH 요청하기

FHIR 번들을 사용하여 FHIR 리소스에 대해 JSON PATCH 요청을 수행할 수 있습니다. 자세한 내용은 FHIR 번들에서 PATCH 요청 실행을 참조하세요.

번들에서 생성된 리소스에 대한 참조 확인

트랜잭션 번들의 리소스는 대상 시스템에 존재하지 않지만 번들 실행 중 생성된 리소스에 대한 참조를 포함할 수 있습니다. Cloud Healthcare API는 entry.fullUrl 필드를 사용하여 리소스 간의 연결을 확인합니다. 번들에 있는 다른 리소스의 entry.fullUrl 값과 일치하는 참조는 저장소에 있는 해당 리소스의 ID로 다시 작성됩니다. 이 작업은 번들의 작업 순서에 관계없이 성공합니다.

Cloud Healthcare API에서는 다음 형식의 fullUrl이 허용됩니다.

  • urn:uuid:UUID
  • urn:oid:OID
  • 모든 URL
  • RESOURCE_TYPE/RESOURCE_ID 형식의 리소스 이름(예: Patient/123) fullUrl는 번들의 로컬 자리 표시 자이므로 이 형식을 사용하지 않는 것이 좋습니다. 이 경우 저장소의 리소스가 동일한 이름을 가지고 있지만 번들의 리소스가 만들기 작업 결과로 다른 이름으로 확인될 경우 혼동을 줄 수 있습니다.

다음 샘플 번들은 환자 리소스와 환자 리소스를 참조하는 관찰 리소스를 만듭니다.

{
  "resourceType": "Bundle",
  "type": "transaction",
  "entry":[
    {
      "request": {
        "method":"POST",
        "url":"Patient"
      },
      "fullUrl": "urn:uuid:05efabf0-4be2-4561-91ce-51548425acb9",
      "resource": {
        "resourceType":"Patient",
        "gender":"male"
      }
    },
    {
      "request": {
        "method":"POST",
        "url":"Observation"
      },
      "resource": {
        "resourceType":"Observation",
        "subject": {
          "reference": "urn:uuid:05efabf0-4be2-4561-91ce-51548425acb9"
        },
        "status":"preliminary",
        "code": {
          "text":"heart rate"
        }
      }
    }
  ]
}

다음 샘플은 번들 실행 방법을 보여줍니다.

curl

샘플 번들 파일은 코드 샘플의 GitHub 저장소에서 사용할 수 있습니다.

번들을 실행하려면 POST 요청을 수행하고 다음 정보를 지정합니다.

  • 상위 데이터 세트와 FHIR 저장소의 이름 및 위치
  • Cloud Storage에서 번들 파일의 위치
  • 액세스 토큰

다음 샘플은 curl을 사용하는 POST 요청을 보여줍니다.

curl -X POST \
    -H "Content-Type: application/fhir+json; charset=utf-8" \
    -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
    --data @BUNDLE_FILE.json \
    "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir"

다음 샘플 번들은 위 예시를 성공적으로 실행한 출력입니다. 첫 번째 항목은 환자 만들기 작업의 성공을 나타내고 새 리소스의 ID를 포함합니다. 두 번째 항목은 관찰 만들기 작업의 성공을 나타내고 새 리소스의 ID를 포함합니다.

{
  "entry": [
    {
      "response": {
        "etag": "ETAG1",
        "lastModified": "2020-08-04T16:14:14.273976+00:00",
        "location": "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/REGION/datasets/REGION/fhirStores/FHIR_STORE_ID/fhir/Patient/PATIENT_ID/_history/HISTORY_ID",
        "status": "201 Created"
      }
    },
    {
      "response": {
        "etag": "ETAG",
        "lastModified": "2020-08-04T16:14:14.273976+00:00",
        "location": "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/REGION/datasets/REGION/fhirStores/FHIR_STORE_ID/fhir/Observation/OBSERVATION_ID/_history/HISTORY_ID",
        "status": "201 Created"
      }
    }
  ],
  "resourceType": "Bundle",
  "type": "transaction-response"
}

PowerShell

샘플 번들 파일은 코드 샘플의 GitHub 저장소에서 사용할 수 있습니다.

번들을 실행하려면 POST 요청을 수행하고 다음 정보를 지정합니다.

  • 상위 데이터 세트와 FHIR 저장소의 이름 및 위치
  • Cloud Storage에서 번들 파일의 위치
  • 액세스 토큰

다음 샘플은 Windows PowerShell을 사용한 POST 요청을 보여줍니다.

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

Invoke-RestMethod `
  -Method Post `
  -Headers $headers `
  -ContentType: "application/fhir+json" `
  -InFile BUNDLE_FILE.json `
  -Uri "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir" | ConvertTo-Json

다음 샘플 번들은 위 예시를 성공적으로 실행한 출력입니다. 첫 번째 항목은 환자 만들기 작업의 성공을 나타내고 새 리소스의 ID를 포함합니다. 두 번째 항목은 관찰 만들기 작업의 성공을 나타내고 새 리소스의 ID를 포함합니다.

{
  "entry": [
    {
      "response": {
        "etag": "ETAG1",
        "lastModified": "2020-08-04T16:14:14.273976+00:00",
        "location": "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/REGION/datasets/REGION/fhirStores/FHIR_STORE_ID/fhir/Patient/PATIENT_ID/_history/HISTORY_ID",
        "status": "201 Created"
      }
    },
    {
      "response": {
        "etag": "ETAG",
        "lastModified": "2020-08-04T16:14:14.273976+00:00",
        "location": "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/REGION/datasets/REGION/fhirStores/FHIR_STORE_ID/fhir/Observation/OBSERVATION_ID/_history/HISTORY_ID",
        "status": "201 Created"
      }
    }
  ],
  "resourceType": "Bundle",
  "type": "transaction-response"
}