Diese Seite wurde von der Cloud Translation API übersetzt.
Switch to English

FHIR-Ressourcen mithilfe von FHIR-Bundles verwalten

Auf dieser Seite wird erläutert, wie Sie FHIR-Ressourcen durch Ausführen von FHIR-Bundles verwalten. Die Methode ExecuteBundle implementiert die FHIR-Standard-Batch-/Transaktionsinteraktion (DSTU2, STU3 und R4).

FHIR-Sets

Ein FHIR-Bundle enthält ein Array von Einträgen, die jeweils einen Vorgang wie das Erstellen, Aktualisieren oder Löschen einer Ressource wie einer Beobachtung oder eines Patienten darstellen. Weitere Informationen finden Sie in den detaillierten Beschreibungen der Elemente in der Bundle-Ressource.

Wenn ein FHIR-Bundle ausgeführt wird, bestimmt der Bundle-Typ, wie die Vorgänge im Bundle ausgeführt werden. Wenn Sie den Bundle-Typ auf batch setzen, werden die Vorgänge als mehrere unabhängige Anfragen ausgeführt. Wenn Sie den Bundle-Typ auf transaction setzen, werden die Vorgänge als mehrere Anfragen ausgeführt, die voneinander abhängen. Wenn ein Transaktions-Bundle beispielsweise einen Patienten und eine Beobachtung umfasst, wird die Beobachtung nicht erstellt, wenn die Anfrage zum Erstellen eines Patienten fehlschlägt.

Wenn ein Vorgang fehlschlägt, wenn der Bundle-Typ batch ist, führt die Cloud Healthcare API die verbleibenden Vorgänge im Bundle aus. Wenn ein Vorgang fehlschlägt, wenn der Bundle-Typ transaction ist, beendet die Cloud Healthcare API die Ausführung von Vorgängen und die Transaktion wird zurückgesetzt.

Berechtigungen zum Ausführen von Bundles

Die Berechtigungsrolle datasets.fhirStores.fhir.executeBundle ist erforderlich, um Bundles auszuführen. Verwenden Sie zum Erteilen dieser Berechtigung die Rolle healthcare.fhirResourceReader. Die Schritte zum Erteilen dieser Berechtigung finden Sie unter Richtlinie ändern.

Die Cloud Healthcare API prüft die Berechtigungen für jeden Vorgang im Bundle. Wenn Sie die Berechtigung healthcare.fhirResources.create, aber nicht die Berechtigung healthcare.fhirResources.update haben, können Sie nur Bundles ausführen, die healthcare.fhirResources.create-Vorgänge enthalten.

Ein Bundle wird ausgeführt

Verwenden Sie zum Ausführen eines FHIR-Bundles die Methode projects.locations.datasets.fhirStores.fhir.executeBundle.

In den folgenden Beispielen ist BUNDLE.json der Pfad und Dateiname eines JSON-codierten FHIR-Bundles. Sie können das Bundle auch in den Anfragetext einfügen.

Im folgenden Beispiel-Bundle wird eine Patientenressource erstellt und eine andere Patientenressource gelöscht.

{
  "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"
      }
    }
  ]
}

Die folgenden Beispiele zeigen, wie ein Bundle ausgeführt wird.

curl

Stellen Sie zum Ausführen eines Bundles eine POST-Anfrage und geben Sie die folgenden Informationen an:

  • Name und Speicherort des übergeordneten Datasets und FHIR-Speichers
  • Speicherort der Bundle-Datei in Cloud Storage
  • Ein Zugriffstoken

Das folgende Beispiel zeigt eine POST-Anfrage mit curl:

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"

Unabhängig vom Ergebnis der einzelnen Vorgänge gibt der Server nach der Ausführung eines Batchpakets eine JSON-codierte Darstellung einer Bundle-Ressource des Typs batch-response zurück. Die Ressource Bundle enthält einen Eintrag für jeden Eintrag in der Anfrage mit dem Ergebnis der Verarbeitung des Eintrags. Dies kann eine Mischung aus Erfolgs- und Fehlerergebnissen sein.

Wenn ein Transaktionspaket erfolgreich ist, gibt der Server eine JSON-codierte Darstellung einer Bundle-Ressource vom Typ transaction-response zurück, die einen Eintrag für jeden Eintrag in der Anfrage mit dem erfolgreichen Ergebnis des Vorgangs enthält.

Wenn während der Ausführung eines Transaktionspakets ein Fehler auftritt, enthält der Antworttext kein Paket. Stattdessen enthält es eine JSON-codierte OperationOutcome-Ressource, die die Fehlerursache beschreibt. Erfolgreiche Vorgänge, für die ein Rollback durchgeführt wurde, werden in der Antwort nicht aufgeführt.

Das folgende Beispiel-Bundle ist die Ausgabe der erfolgreichen Ausführung des obigen Beispiels. Der erste Eintrag gibt den Erfolg des Vorgangs zum Erstellen eines Patienten an und enthält die ID der neuen Ressource. Der zweite Eintrag gibt den Erfolg des Löschvorgangs an.

{
  "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

Stellen Sie zum Ausführen eines Bundles eine POST-Anfrage und geben Sie die folgenden Informationen an:

  • Name und Speicherort des übergeordneten Datasets und FHIR-Speichers
  • Speicherort der Bundle-Datei in Cloud Storage
  • Ein Zugriffstoken

Das folgende Beispiel zeigt eine POST-Anfrage mit Windows PowerShell.

$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

Unabhängig vom Ergebnis der einzelnen Vorgänge gibt der Server nach der Ausführung eines Batchpakets eine JSON-codierte Darstellung einer Bundle-Ressource des Typs batch-response zurück. Die Ressource Bundle enthält einen Eintrag für jeden Eintrag in der Anfrage mit dem Ergebnis der Verarbeitung des Eintrags. Dies kann eine Mischung aus Erfolgs- und Fehlerergebnissen sein.

Wenn ein Transaktionspaket erfolgreich ist, gibt der Server eine JSON-codierte Darstellung einer Bundle-Ressource vom Typ transaction-response zurück, die einen Eintrag für jeden Eintrag in der Anfrage mit dem erfolgreichen Ergebnis des Vorgangs enthält.

Wenn während der Ausführung eines Transaktionspakets ein Fehler auftritt, enthält der Antworttext kein Paket. Stattdessen enthält es eine JSON-codierte OperationOutcome-Ressource, die die Fehlerursache beschreibt. Erfolgreiche Vorgänge, für die ein Rollback durchgeführt wurde, werden in der Antwort nicht aufgeführt.

Das folgende Beispiel-Bundle ist die Ausgabe der erfolgreichen Ausführung des obigen Beispiels. Der erste Eintrag gibt den Erfolg des Vorgangs zum Erstellen eines Patienten an und enthält die ID der neuen Ressource. Der zweite Eintrag gibt den Erfolg des Löschvorgangs an.

{
  "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: %v", 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,
				},
			},
		},
	}
	jsonPayload, err := json.Marshal(payload)
	if err != nil {
		return fmt.Errorf("json.Encode: %v", 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: %v", err)
	}
	defer resp.Body.Close()

	respBytes, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return fmt.Errorf("could not read response: %v", 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.jackson2.JacksonFactory;
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 JacksonFactory();
  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

Ein Beispiel für eine Bundle-Datei ist im GitHub-Repository des Codebeispiels verfügbar.

const {google} = require('googleapis');
const healthcare = google.healthcare('v1');
const fs = require('fs');

async function executeFhirBundle() {
  const auth = await google.auth.getClient({
    scopes: ['https://www.googleapis.com/auth/cloud-platform'],
  });

  google.options({auth, headers: {'Content-Type': 'application/fhir+json'}});

  // 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

Ein Beispiel für eine Bundle-Datei ist im GitHub-Repository des Codebeispiels verfügbar.

def execute_bundle(
    base_url, project_id, cloud_region, dataset_id, fhir_store_id, bundle,
):
    """Executes the operations in the given bundle."""
    url = "{}/projects/{}/locations/{}".format(base_url, project_id, cloud_region)

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

    # Make an authenticated API request
    session = get_session()

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

    with open(bundle, "r") 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("Executed bundle from file: {}".format(bundle))
    print(json.dumps(resource, indent=2))

    return resource

Verweise auf Ressourcen in einem Bundle aufheben

Ressourcen in einem Transaktionsset können Verweise auf Ressourcen enthalten, die im Zielsystem nicht vorhanden sind, aber während der Bundle-Ausführung erstellt werden. Die Cloud Healthcare API löst die Zuordnung zwischen den Ressourcen mithilfe des Felds entry.fullUrl auf. Referenzen, die mit dem entry.fullUrl-Wert einer anderen Ressource im Bundle entsprechen, werden in die ID der entsprechenden Ressource im Speicher umgeschrieben. Dieser Vorgang ist unabhängig von der Reihenfolge der Vorgänge im Bundle erfolgreich.

Die Cloud Healthcare API akzeptiert die fullUrl in den folgenden Formaten:

  • urn:uuid:UUID
  • urn:oid:OID
  • einer beliebigen URL
  • einem Ressourcennamen im Format RESOURCE_TYPE/RESOURCE_ID, z. B. Patient/123. Die Verwendung dieses Formats wird nicht empfohlen, da fullUrl ein Platzhalter für das Bundle ist. Dies kann Verwirrung stiften, wenn eine Ressource im Speicher den gleichen Namen hat, aber die Ressource im Bundle aufgrund eines Erstellungsvorgangs in einen anderen Namen aufgelöst wird.

Im folgenden Beispiel-Bundle werden eine Patientenressource und eine Beobachtungsressource erstellt, die sich auf die Patientenressource bezieht.

{
  "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"
        }
      }
    }
  ]
}

Die folgenden Beispiele zeigen, wie ein Bundle ausgeführt wird.

curl

Ein Beispiel für eine Bundle-Datei ist im GitHub-Repository des Codebeispiels verfügbar.

Stellen Sie zum Ausführen eines Bundles eine POST-Anfrage und geben Sie die folgenden Informationen an:

  • Name und Speicherort des übergeordneten Datasets und FHIR-Speichers
  • Speicherort der Bundle-Datei in Cloud Storage
  • Ein Zugriffstoken

Das folgende Beispiel zeigt eine POST-Anfrage mit curl:

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"

Das folgende Beispiel-Bundle ist die Ausgabe der erfolgreichen Ausführung des obigen Beispiels. Der erste Eintrag gibt den Erfolg des Vorgangs zum Erstellen eines Patienten an und enthält die ID der neuen Ressource. Der zweite Eintrag gibt den Erfolg des Vorgangs zum Erstellen der Beobachtung an und enthält die ID der neuen Ressource.

{
  "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

Ein Beispiel für eine Bundle-Datei ist im GitHub-Repository des Codebeispiels verfügbar.

Stellen Sie zum Ausführen eines Bundles eine POST-Anfrage und geben Sie die folgenden Informationen an:

  • Name und Speicherort des übergeordneten Datasets und FHIR-Speichers
  • Speicherort der Bundle-Datei in Cloud Storage
  • Ein Zugriffstoken

Das folgende Beispiel zeigt eine POST-Anfrage mit Windows PowerShell.

$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

Das folgende Beispiel-Bundle ist die Ausgabe der erfolgreichen Ausführung des obigen Beispiels. Der erste Eintrag gibt den Erfolg des Vorgangs zum Erstellen eines Patienten an und enthält die ID der neuen Ressource. Der zweite Eintrag gibt den Erfolg des Vorgangs zum Erstellen der Beobachtung an und enthält die ID der neuen Ressource.

{
  "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"
}