

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 捆绑 FHIR 资源
<a name="managing-fhir-resources-bundle"></a>

FHIR `Bundle` 是存放 FHIR 资源集合的容器。 AWS HealthLake AWS HealthLake 支持两种具有不同处理行为的捆绑包。

[https://hl7.org/fhir/R4/http.html#transaction](https://hl7.org/fhir/R4/http.html#transaction)捆绑包独立处理每种资源。如果一个资源出现故障，其余资源仍然可以成功。每个操作都是单独处理的，即使某些操作失败，处理也会继续进行。在可以接受部分成功的情况下，使用批量捆绑包进行批量操作，例如上传多份不相关的患者记录。

[https://hl7.org/fhir/R4/http.html#transaction](https://hl7.org/fhir/R4/http.html#transaction)bundle 以原子方式将所有资源作为一个单元处理。要么所有资源操作都成功，要么都不 AWS HealthLake 提交。当您需要保证相关资源的参照完整性时，请使用交易捆绑包，例如创建具有相关观察结果和病症的患者，其中必须将所有数据记录在一起。


**批量捆绑包和交易捆绑包之间的区别**  

| 功能 | Batch | 事务 | 
| --- | --- | --- | 
| 处理模型 | 每个操作的成功或失败都是独立的。 | 所有操作都以单个原子单元的形式成功或失败。 | 
| 故障处理 | 即使个别操作失败，处理也会继续。 | 如果任何一个操作失败，则整个捆绑包将失败。 | 
| 执行顺序 | 不能保证执行顺序。 | 操作按指定的顺序处理。 | 
| 参照完整性 | 未在所有操作中强制执行。 | 对捆绑包中本地引用的资源强制执行。 | 
| 最适合用于 | 可以接受部分成功的批量操作。 | 必须一起创建或更新的相关资源。 | 

您可以捆绑相同或不同类型的 FHIR 资源，它们可以混合使用 FHIR 操作，例如、`create`、`read``update``delete`、和。`patch`有关更多信息，请参阅 **FHIR R4 文档**中的[资源包](https://hl7.org/fhir/R4/Bundle)。

以下是每种捆绑包类型的示例用例。

Batch 捆绑包  
+ 在夜间数据同步期间，上传来自不同设施的多份无关患者记录。
+ 批量上传历史用药记录，其中一些记录可能存在验证问题。
+ 加载参考数据，例如组织和从业人员，其中个人失败不会影响其他条目。

交易捆绑包  
+ 在急诊室住院期间，创建具有相关观察结果和状况的患者，所有数据都必须一起记录。
+ 更新患者的药物清单和相关的过敏信息，这些信息必须保持一致。
+ 将与患者的完整相遇、观察结果、程序和账单信息记录为单个原子单元。

**重要**  
批处理和交易捆绑包使用相同的`Bundle`资源结构。唯一的区别是`type`字段的值。

以下示例显示了具有多种资源类型和操作的事务捆绑包。

```
{
  "resourceType": "Bundle",
  "type": "transaction",
  "entry": [
    {
      "fullUrl": "urn:uuid:4f6a30fb-cd3c-4ab6-8757-532101f72065",
      "resource": {
        "resourceType": "Patient",
        "id": "new-patient",
        "active": true,
        "name": [
          {
            "family": "Johnson",
            "given": [
              "Sarah"
            ]
          }
        ],
        "gender": "female",
        "birthDate": "1985-08-12",
        "telecom": [
          {
            "system": "phone",
            "value": "555-123-4567",
            "use": "home"
          }
        ]
      },
      "request": {
        "method": "POST",
        "url": "Patient"
      }
    },
    {
      "fullUrl": "urn:uuid:7f83f473-d8cc-4a8d-86d3-9d9876a3248b",
      "resource": {
        "resourceType": "Observation",
        "id": "blood-pressure",
        "status": "final",
        "code": {
          "coding": [
            {
              "system": "http://loinc.org",
              "code": "85354-9",
              "display": "Blood pressure panel"
            }
          ],
          "text": "Blood pressure panel"
        },
        "subject": {
          "reference": "urn:uuid:4f6a30fb-cd3c-4ab6-8757-532101f72065"
        },
        "effectiveDateTime": "2023-10-15T09:30:00Z",
        "component": [
          {
            "code": {
              "coding": [
                {
                  "system": "http://loinc.org",
                  "code": "8480-6",
                  "display": "Systolic blood pressure"
                }
              ]
            },
            "valueQuantity": {
              "value": 120,
              "unit": "mmHg",
              "system": "http://unitsofmeasure.org",
              "code": "mm[Hg]"
            }
          },
          {
            "code": {
              "coding": [
                {
                  "system": "http://loinc.org",
                  "code": "8462-4",
                  "display": "Diastolic blood pressure"
                }
              ]
            },
            "valueQuantity": {
              "value": 80,
              "unit": "mmHg",
              "system": "http://unitsofmeasure.org",
              "code": "mm[Hg]"
            }
          }
        ]
      },
      "request": {
        "method": "POST",
        "url": "Observation"
      }
    },
    {
      "resource": {
        "resourceType": "Appointment",
        "id": "appointment-123",
        "status": "booked",
        "description": "Annual physical examination",
        "start": "2023-11-15T09:00:00Z",
        "end": "2023-11-15T09:30:00Z",
        "participant": [
          {
            "actor": {
              "reference": "urn:uuid:4f6a30fb-cd3c-4ab6-8757-532101f72065"
            },
            "status": "accepted"
          }
        ]
      },
      "request": {
        "method": "PUT",
        "url": "Appointment/appointment-123"
      }
    },
    {
      "request": {
        "method": "DELETE",
        "url": "MedicationRequest/med-request-456"
      }
    }
  ]
}
```

## 将 FHIR 资源捆绑为独立实体
<a name="bundle-fhir-resources-batch-type"></a>

**将 FHIR 资源捆绑为独立实体**  


1. 收集 HealthLake `region`和`datastoreId`价值。有关更多信息，请参阅 [获取数据存储属性](managing-data-stores-describe.md)。

1. 使用收集到的 HealthLake`region`和值为请求构造一个 URL `datastoreId`。请*勿*在 URL 中指定 FHIR 资源类型。要查看以下示例中的整个 URL 路径，请滚动到 “**复制**” 按钮。

   ```
   POST https://healthlake.region.amazonaws.com/datastore/datastoreId/r4/
   ```

1. 为请求构造一个 JSON 正文，将每个 HTTP 动词指定为`method`元素的一部分。以下示例使用与`Bundle`资源的`batch`类型交互来创建新的`Patient`和`Medication`资源。所有必填部分都有相应的注释。出于本过程的目的，请将文件另存为`batch-independent.json`。

   ```
   {
       "resourceType": "Bundle",
       "id": "bundle-batch",
       "meta": {
           "lastUpdated": "2014-08-18T01:43:30Z"
       },
       "type": "batch",
       "entry": [
           {
               "resource": {
                   "resourceType": "Patient",
                   "meta": {
                       "lastUpdated": "2022-06-03T17:53:36.724Z"
                   },
                   "text": {
                       "status": "generated",
                       "div": "Some narrative"
                   },
                   "active": true,
                   "name": [
                       {
                           "use": "official",
                           "family": "Jackson",
                           "given": [
                               "Mateo",
                               "James"
                           ]
                       }
                   ],
                   "gender": "male",
                   "birthDate": "1974-12-25"
               },
               "request": {
                   "method": "POST",
                   "url": "Patient"
               }
           },
           {
               "resource": {
                   "resourceType": "Medication",
                   "id": "med0310",
                   "contained": [
                       {
                           "resourceType": "Substance",
                           "id": "sub03",
                           "code": {
                               "coding": [
                                   {
                                       "system": "http://snomed.info/sct",
                                       "code": "55452001",
                                       "display": "Oxycodone (substance)"
                                   }
                               ]
                           }
                       }
                   ],
                   "code": {
                       "coding": [
                           {
                               "system": "http://snomed.info/sct",
                               "code": "430127000",
                               "display": "Oral Form Oxycodone (product)"
                           }
                       ]
                   },
                   "form": {
                       "coding": [
                           {
                               "system": "http://snomed.info/sct",
                               "code": "385055001",
                               "display": "Tablet dose form (qualifier value)"
                           }
                       ]
                   },
                   "ingredient": [
                       {
                           "itemReference": {
                               "reference": "#sub03"
                           },
                           "strength": {
                               "numerator": {
                                   "value": 5,
                                   "system": "http://unitsofmeasure.org",
                                   "code": "mg"
                               },
                               "denominator": {
                                   "value": 1,
                                   "system": "http://terminology.hl7.org/CodeSystem/v3-orderableDrugForm",
                                   "code": "TAB"
                               }
                           }
                       }
                   ]
               },
               "request": {
                   "method": "POST",
                   "url": "Medication"
               }
           }
       ]
   }
   ```

1. 发送 请求。FHIR `Bundle` 批处理类型使用具有[AWS 签名版本 4](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_sigv.html) 或 FHIR 授权的 SMART `POST` 请求。以下代码示例使用`curl`命令行工具进行演示。

------
#### [ SigV4 ]

   Sigv4 授权

   ```
   curl --request POST \
     'https://healthlake.region.amazonaws.com/datastore/datastoreId/r4/' \
     --aws-sigv4 'aws:amz:region:healthlake' \
     --user "$AWS_ACCESS_KEY_ID:$AWS_SECRET_ACCESS_KEY" \
     --header "x-amz-security-token:$AWS_SESSION_TOKEN" \
     --header 'Accept: application/json' \
     --data @batch-type.json
   ```

------
#### [ SMART on FHIR ]

   该[https://docs.aws.amazon.com/healthlake/latest/APIReference/API_IdentityProviderConfiguration.html](https://docs.aws.amazon.com/healthlake/latest/APIReference/API_IdentityProviderConfiguration.html)数据类型的 SMART on FHIR 授权示例。

   ```
   {
       "AuthorizationStrategy": "SMART_ON_FHIR",
       "FineGrainedAuthorizationEnabled": true,
       "IdpLambdaArn": "arn:aws:lambda:your-region:your-account-id:function:your-lambda-name",
       "Metadata": "{\"issuer\":\"https://ehr.example.com\", \"jwks_uri\":\"https://ehr.example.com/.well-known/jwks.json\",\"authorization_endpoint\":\"https://ehr.example.com/auth/authorize\",\"token_endpoint\":\"https://ehr.token.com/auth/token\",\"token_endpoint_auth_methods_supported\":[\"client_secret_basic\",\"foo\"],\"grant_types_supported\":[\"client_credential\",\"foo\"],\"registration_endpoint\":\"https://ehr.example.com/auth/register\",\"scopes_supported\":[\"openId\",\"profile\",\"launch\"],\"response_types_supported\":[\"code\"],\"management_endpoint\":\"https://ehr.example.com/user/manage\",\"introspection_endpoint\":\"https://ehr.example.com/user/introspect\",\"revocation_endpoint\":\"https://ehr.example.com/user/revoke\",\"code_challenge_methods_supported\":[\"S256\"],\"capabilities\":[\"launch-ehr\",\"sso-openid-connect\",\"client-public\",\"permission-v2\"]}"
   }
   ```

   调用者可以在授权 lambda 中分配权限。有关更多信息，请参阅 [OAuth 2.0 瞄准镜](reference-smart-on-fhir-oauth-scopes.md)。

------

   服务器返回一个响应，其中显示`Patient`了作为`Bundle`批处理类型请求的结果而创建的和`Medication`资源。

## 以捆绑包 PUTs 为条件
<a name="bundle-conditional-PUTs"></a>

AWS HealthLake 支持使用以下查询参数在捆绑包中进行条件更新：
+ `_id`（独立）
+ `_id`与以下选项之一相结合：
  + `_tag`
  + `_createdAt`
  + `_lastUpdated`

当您在捆绑包 PUTs 中使用条件时，会根据现有资源 AWS HealthLake 评估查询参数，并根据匹配结果采取行动。


**有条件的更新行为**  

| 场景 | HTTP 状态 | 已采取的行动 | 
| --- | --- | --- | 
| 提供没有 ID 的资源 | 201 已创建 | 始终创建新资源。 | 
| 具有新 ID 的资源（不匹配） | 201 已创建 | 使用指定 ID 创建新资源。 | 
| 具有现有 ID 的资源（单一匹配） | 200 OK (200 确定) | 更新匹配的资源。 | 
| 具有现有 ID 的资源（检测到冲突） | 409 冲突 | 返回错误。未进行任何更改。 | 
| 具有现有 ID 的资源（ID 不匹配） | 400 错误请求 | 返回错误。未进行任何更改。 | 
| 多个资源匹配条件 | 412 前提条件失败 | 返回错误。未进行任何更改。 | 

在以下带有条件更新的捆绑包示例中，带有 FHIR ID 的`Patient`资源仅在满足条件`_lastUpdated=lt2025-04-20`时才会`476`更新。

```
{
    "resourceType": "Bundle",
    "id": "bundle-batch",
    "meta": {
        "lastUpdated": "2014-08-18T01:43:30Z"
    },
    "type": "batch",
    "entry": [
        {
            "resource": {
                "resourceType": "Patient",
                "id": "476",
                "meta": {
                    "lastUpdated": "2022-06-03T17:53:36.724Z"
                },
                "active": true,
                "name": [
                    {
                        "use": "official",
                        "family": "Jackson",
                        "given": [
                            "Mateo",
                            "James"
                        ]
                    }
                ],
                "gender": "male",
                "birthDate": "1974-12-25"
            },
            "request": {
                "method": "PUT",
                "url": "Patient?_id=476&_lastUpdated=lt2025-04-20"
            }
        },
        {
            "resource": {
                "resourceType": "Medication",
                "id": "med0310",
                "contained": [
                    {
                        "resourceType": "Substance",
                        "id": "sub03",
                        "code": {
                            "coding": [
                                {
                                    "system": "http://snomed.info/sct",
                                    "code": "55452001",
                                    "display": "Oxycodone (substance)"
                                }
                            ]
                        }
                    }
                ],
                "code": {
                    "coding": [
                        {
                            "system": "http://snomed.info/sct",
                            "code": "430127000",
                            "display": "Oral Form Oxycodone (product)"
                        }
                    ]
                },
                "form": {
                    "coding": [
                        {
                            "system": "http://snomed.info/sct",
                            "code": "385055001",
                            "display": "Tablet dose form (qualifier value)"
                        }
                    ]
                },
                "ingredient": [
                    {
                        "itemReference": {
                            "reference": "#sub03"
                        },
                        "strength": {
                            "numerator": {
                                "value": 5,
                                "system": "http://unitsofmeasure.org",
                                "code": "mg"
                            },
                            "denominator": {
                                "value": 1,
                                "system": "http://terminology.hl7.org/CodeSystem/v3-orderableDrugForm",
                                "code": "TAB"
                            }
                        }
                    }
                ]
            },
            "request": {
                "method": "POST",
                "url": "Medication"
            }
        }
    ]
}
```

## 将 FHIR 资源捆绑为一个实体
<a name="bundle-fhir-resources-document-type"></a>

**将 FHIR 资源捆绑为单个实体**  


1. 收集 HealthLake `region`和`datastoreId`价值。有关更多信息，请参阅 [获取数据存储属性](managing-data-stores-describe.md)。

1. 使用收集到的 HealthLake`region`和值为请求构造一个 URL `datastoreId`。将 FHIR 资源类型`Bundle`作为网址的一部分。要查看以下示例中的整个 URL 路径，请滚动到 “**复制**” 按钮。

   ```
   POST https://healthlake.region.amazonaws.com/datastore/datastoreId/r4/Bundle
   ```

1. 为请求构建 JSON 正文，指定要组合在一起的 FHIR 资源。以下示例将两个`Patient`资源分组在一起 HealthLake。出于本过程的目的，请将文件另存为`batch-single.json`。

   ```
   {
       "resourceType": "Bundle",
       "id": "bundle-minimal",
       "language": "en-US",
       "identifier": {
           "system": "urn:oid:1.2.3.4.5",
           "value": "28b95815-76ce-457b-b7ae-a972e527db4f"
       },
       "type": "document",
       "timestamp": "2020-12-11T14:30:00+01:00",
       "entry": [
           {
               "fullUrl": "urn:uuid:f40b07e3-37e8-48c3-bf1c-ae70fe12dabf",
               "resource": {
                   "resourceType": "Composition",
                   "id": "f40b07e3-37e8-48c3-bf1c-ae70fe12dabf",
                   "status": "final",
                   "type": {
                       "coding": [
                           {
                               "system": "http://loinc.org",
                               "code": "60591-5",
                               "display": "Patient summary Document"
                           }
                       ]
                   },
                   "date": "2020-12-11T14:30:00+01:00",
                   "author": [
                       {
                           "reference": "urn:uuid:45271f7f-63ab-4946-970f-3daaaa0663ff"
                       }
                   ],
                   "title": "Patient Summary as of December 7, 2020 14:30"
               }
           },
           {
               "fullUrl": "urn:uuid:45271f7f-63ab-4946-970f-3daaaa0663ff",
               "resource": {
                   "resourceType": "Practitioner",
                   "id": "45271f7f-63ab-4946-970f-3daaaa0663ff",
                   
                   "active": true,
                   "name": [
                       {
                           "family": "Doe",
                           "given": [
                               "John"
                           ]
                       }
                   ]                
               }
           }
       ]
   }
   ```

1. 发送 请求。FHIR `Bundle` 文档类型使用带有[AWS 签名版本 4 签名](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_sigv.html)协议的`POST`请求。以下代码示例使用`curl`命令行工具进行演示。

------
#### [ SigV4 ]

   Sigv4 授权

   ```
   curl --request POST \
     'https://healthlake.region.amazonaws.com/datastore/datastoreId/r4/Bundle' \
     --aws-sigv4 'aws:amz:region:healthlake' \
     --user "$AWS_ACCESS_KEY_ID:$AWS_SECRET_ACCESS_KEY" \
     --header "x-amz-security-token:$AWS_SESSION_TOKEN" \
     --header 'Accept: application/json' \
     --data @document-type.json
   ```

------
#### [ SMART on FHIR ]

   该[https://docs.aws.amazon.com/healthlake/latest/APIReference/API_IdentityProviderConfiguration.html](https://docs.aws.amazon.com/healthlake/latest/APIReference/API_IdentityProviderConfiguration.html)数据类型的 SMART on FHIR 授权示例。

   ```
   {
       "AuthorizationStrategy": "SMART_ON_FHIR",
       "FineGrainedAuthorizationEnabled": true,
       "IdpLambdaArn": "arn:aws:lambda:your-region:your-account-id:function:your-lambda-name",
       "Metadata": "{\"issuer\":\"https://ehr.example.com\", \"jwks_uri\":\"https://ehr.example.com/.well-known/jwks.json\",\"authorization_endpoint\":\"https://ehr.example.com/auth/authorize\",\"token_endpoint\":\"https://ehr.token.com/auth/token\",\"token_endpoint_auth_methods_supported\":[\"client_secret_basic\",\"foo\"],\"grant_types_supported\":[\"client_credential\",\"foo\"],\"registration_endpoint\":\"https://ehr.example.com/auth/register\",\"scopes_supported\":[\"openId\",\"profile\",\"launch\"],\"response_types_supported\":[\"code\"],\"management_endpoint\":\"https://ehr.example.com/user/manage\",\"introspection_endpoint\":\"https://ehr.example.com/user/introspect\",\"revocation_endpoint\":\"https://ehr.example.com/user/revoke\",\"code_challenge_methods_supported\":[\"S256\"],\"capabilities\":[\"launch-ehr\",\"sso-openid-connect\",\"client-public\",\"permission-v2\"]}"
   }
   ```

   调用者可以在授权 lambda 中分配权限。有关更多信息，请参阅 [OAuth 2.0 瞄准镜](reference-smart-on-fhir-oauth-scopes.md)。

------

   服务器返回一个响应，其中显示了由于`Bundle`文档类型请求而创建的两个`Patient`资源。

## 为捆绑包配置验证级别
<a name="validation-level-bundles"></a>

捆绑 FHIR 资源时，您可以选择指定 `x-amzn-healthlake-fhir-validation-level` HTTP 标头来配置资源的验证级别。将为捆绑包中的所有创建和更新请求设置此验证级别。 AWS HealthLake 目前支持以下验证级别：
+ `strict`：根据资源的配置文件元素对资源进行验证，如果不存在配置文件，则根据R4规格进行验证。这是的默认验证级别 AWS HealthLake。
+ `structure-only`：根据 R4 对资源进行验证，忽略任何引用的配置文件。
+ `minimal`：资源经过最低限度的验证，忽略了某些 R4 规则。未通过所需的结构检查的资源 search/analytics 将进行更新，以包括审计警告。

尽管搜索索引需要验证失败，但与最低验证级别捆绑在一起的资源仍可能会被提取到数据存储中。在这种情况下，资源将更新为包含用于记录上述故障的 Healthlake 专用扩展程序，Bundle 响应中的条目将包括以下 OperationOutcome 资源：

```
{
    "resourceType": "Bundle",
    "type": "batch-response",
    "timestamp": "2025-08-25T22:58:48.846287342Z",
    "entry": [
        {
            "response": {
                "status": "201",
                "location": "Patient/195abc49-ba8e-4c8b-95c2-abc88fef7544/_history/1",
                "etag": "W/\"1\"",
                "lastModified": "2025-08-25T22:58:48.801245445Z",
                "outcome": {
                    "resourceType": "OperationOutcome",
                    "issue": [
                        {
                            "severity": "error",
                            "code": "processing",
                            "details": {
                                "text": "FHIR resource in payload failed FHIR validation rules."
                            },
                            "diagnostics": "FHIR resource in payload failed FHIR validation rules."
                        }
                    ]
                }
            }
        }
    ]
}
```

此外，将包含以下 HTTP 响应标头，其值为 “true”：

```
x-amzn-healthlake-validation-issues : true
```

**注意**  
请注意，如果存在这些错误，则根据 R4 规范提取的数据可能无法按预期进行搜索。

## 对捆绑包类型 “消息” 的支持有限
<a name="bundle-message-type-limited-support"></a>

HealthLake `message`通过内部转换过程对 FHIR 捆绑包类型提供有限的支持。此支持专为无法在源头重新格式化消息包的场景而设计，例如从传统医院系统中摄取 ADT（入院、出院、转移）提要。

**警告**  
此功能需要明确的 AWS 账户许可名单，并且不强制执行 FHIR R4 消息语义或引用完整性。在使用消息包之前，请联系 Su AWS pport 申请启用您的账户。

### 与标准邮件处理的主要区别
<a name="bundle-message-key-differences"></a>
+ **消息包**（FHIR 规范）：第一个条目必须是引用其他`MessageHeader`资源的条目。资源缺少单个`request`对象， MessageHeader 事件决定处理操作。
+ **HealthLake 处理**：通过自动为每个资源条目分配 PUT 操作，将消息包转换为批量捆绑包。资源是独立处理的，不强制执行消息语义或引用完整性。

### 重要限制
<a name="bundle-message-limitations"></a>
+ 未强制执行 FHIR R4 邮件特定的处理规则
+ 资源之间没有交易完整性
+ 资源间引用未经过验证
+ 需要明确的账户许可名单

### 消息包结构示例
<a name="bundle-message-example"></a>

```
{
              "resourceType": "Bundle",
              "type": "message",
              "entry": [
                {
                  "resource": {
                    "resourceType": "MessageHeader",
                    "eventCoding": {
                      "system": "http://hl7.org/fhir/us/davinci-alerts/CodeSystem/notification-event",
                      "code": "notification-admit"
                    },
                    "focus": [{"reference": "Encounter/example-id"}]
                  }
                },
                {
                  "resource": {"resourceType": "Patient", "id": "example-id"}
                },
                {
                  "resource": {"resourceType": "Encounter", "id": "example-id"}
                }
              ]
            }
```

**注意**  
每个资源都是独立存储的，就像通过单独的 PUT 操作提交一样。如果需要完整的 FHIR 消息语义或参照完整性验证，请在提交之前对消息包进行预处理或实现应用程序级验证。

## 异步捆绑交易
<a name="managing-fhir-resources-async-transactions"></a>

AWS HealthLake 支持异步`Bundle`类型`transaction`，允许您提交包含最多 500 个资源的交易。当您提交异步事务时，会将其 HealthLake 排队等候处理，并立即返回轮询网址。您可以使用此 URL 来检查状态并检索响应。这遵循 [FHIR 异步捆绑包模式](https://hl7.org/fhir/async-bundle.html)。

**何时使用异步事务**  

+ 您需要在单笔交易中提交 100 个以上的资源（同步限制）。
+ 您希望避免在等待事务处理完成时阻塞应用程序。
+ 您需要以更高的吞吐量处理大量相关资源。

**重要**  
投票结果将在交易完成后的90天内公布。在这90天之后，轮询网址将不再返回结果。设计您的集成，以便在此窗口中检索和存储结果。

**注意**  
同步`Bundle`类型`transaction`继续支持多达 100 个资源，并且是默认的处理模式。如果您提交的资源超过 100 个`transaction`，但没有`Prefer: respond-async`标题的`Bundle`类型， HealthLake 则会返回`422 Unprocessable Entity`错误。异步处理`batch`不支持带类型的捆绑包，只能异步提交`Bundle`类型`transaction`（最多有 500 个操作）。

### 提交异步事务
<a name="async-transactions-submitting"></a>

要提交异步事务，请向数据存储端点发送带有`Prefer: respond-async`标头的`POST`请求。捆绑包必须有类型`transaction`。异步分发包处理`batch`不支持类型为 bundle。

HealthLake 在提交时对捆绑包进行初始验证。如果验证成功，则 HealthLake 返回 HTTP 202 Accepted，并返回包含轮询网址的`content-location`响应标头。

**提交异步`Bundle`类型 `transaction`**  


1. 向 HealthLake 数据存储端点发送`POST`请求。

   ```
   POST https://healthlake.region.amazonaws.com/datastore/datastoreId/r4/
   ```

1. 使用捆绑包类型为请求构造一个 JSON 正文`transaction`。出于本过程的目的，请将文件另存为`async-transaction.json`。

   ```
   {
       "resourceType": "Bundle",
       "type": "transaction",
       "entry": [
           {
               "resource": {
                   "resourceType": "Patient",
                   "active": true,
                   "name": [
                       {
                           "use": "official",
                           "family": "Smith",
                           "given": ["Jane"]
                       }
                   ],
                   "gender": "female",
                   "birthDate": "1990-01-15"
               },
               "request": {
                   "method": "POST",
                   "url": "Patient"
               }
           },
           {
               "resource": {
                   "resourceType": "Observation",
                   "status": "final",
                   "code": {
                       "coding": [
                           {
                               "system": "http://loinc.org",
                               "code": "85354-9",
                               "display": "Blood pressure panel"
                           }
                       ]
                   },
                   "subject": {
                       "reference": "urn:uuid:example-patient-id"
                   }
               },
               "request": {
                   "method": "POST",
                   "url": "Observation"
               }
           }
       ]
   }
   ```

1. 发送带有`Prefer: respond-async`标题的请求。FHIR `Bundle` 交易类型使用具有[AWS 签名版本 4](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_sigv.html) 或 FHIR 授权的 SMART `POST` 请求。以下代码示例使用`curl`命令行工具进行演示。

------
#### [ SigV4 ]

   Sigv4 授权

   ```
   curl --request POST \
     'https://healthlake.region.amazonaws.com/datastore/datastoreId/r4/' \
     --aws-sigv4 'aws:amz:region:healthlake' \
     --user "$AWS_ACCESS_KEY_ID:$AWS_SECRET_ACCESS_KEY" \
     --header "x-amz-security-token:$AWS_SESSION_TOKEN" \
     --header 'Accept: application/json' \
     --header 'Prefer: respond-async' \
     --data @async-transaction.json
   ```

------
#### [ SMART on FHIR ]

   该[https://docs.aws.amazon.com/healthlake/latest/APIReference/API_IdentityProviderConfiguration.html](https://docs.aws.amazon.com/healthlake/latest/APIReference/API_IdentityProviderConfiguration.html)数据类型的 SMART on FHIR 授权示例。

   ```
   {
       "AuthorizationStrategy": "SMART_ON_FHIR",
       "FineGrainedAuthorizationEnabled": true,
       "IdpLambdaArn": "arn:aws:lambda:your-region:your-account-id:function:your-lambda-name",
       "Metadata": "{\"issuer\":\"https://ehr.example.com\", \"jwks_uri\":\"https://ehr.example.com/.well-known/jwks.json\",\"authorization_endpoint\":\"https://ehr.example.com/auth/authorize\",\"token_endpoint\":\"https://ehr.token.com/auth/token\",\"token_endpoint_auth_methods_supported\":[\"client_secret_basic\",\"foo\"],\"grant_types_supported\":[\"client_credential\",\"foo\"],\"registration_endpoint\":\"https://ehr.example.com/auth/register\",\"scopes_supported\":[\"openId\",\"profile\",\"launch\"],\"response_types_supported\":[\"code\"],\"management_endpoint\":\"https://ehr.example.com/user/manage\",\"introspection_endpoint\":\"https://ehr.example.com/user/introspect\",\"revocation_endpoint\":\"https://ehr.example.com/user/revoke\",\"code_challenge_methods_supported\":[\"S256\"],\"capabilities\":[\"launch-ehr\",\"sso-openid-connect\",\"client-public\",\"permission-v2\"]}"
   }
   ```

   调用者可以在授权 lambda 中分配权限。有关更多信息，请参阅 [OAuth 2.0 瞄准镜](reference-smart-on-fhir-oauth-scopes.md)。

------

1. 成功提交后，服务器返回 HTTP 202 已接受。`content-location`响应标头包含轮询网址。响应正文是一种`OperationOutcome`资源。

   ```
   HTTP/1.1 202 Accepted
   content-location: https://healthlake.region.amazonaws.com/datastore/datastoreId/r4/Transaction/transactionId
   ```

   ```
   {
       "resourceType": "OperationOutcome",
       "issue": [
           {
               "severity": "information",
               "code": "informational",
               "diagnostics": "Submitted Asynchronous Bundle Transaction",
               "location": [
                   "https://healthlake.region.amazonaws.com/datastore/datastoreId/r4/Transaction/transactionId"
               ]
           }
       ]
   }
   ```

### 轮询交易状态
<a name="async-transactions-polling"></a>

提交异步事务后，使用`content-location`响应标头中的轮询网址来检查交易状态。向投票 URL 发送`GET`请求。

**注意**  
对于启用 SMART on FHIR 的数据存储，授权令牌必须包括对`Transaction`资源类型的`read`权限，以轮询交易状态。有关 FHIR 作用域上的 SMART 的更多信息，请参阅[支持的 FHIR OAuth 2.0 瞄准镜上的 SMART HealthLake](reference-smart-on-fhir-oauth-scopes.md)。

向投票 URL 发送`GET`请求。以下示例使用`curl`命令行工具。

------
#### [ SigV4 ]

Sigv4 授权

```
curl --request GET \
  'https://healthlake.region.amazonaws.com/datastore/datastoreId/r4/Transaction/transactionId' \
  --aws-sigv4 'aws:amz:region:healthlake' \
  --user "$AWS_ACCESS_KEY_ID:$AWS_SECRET_ACCESS_KEY" \
  --header "x-amz-security-token:$AWS_SESSION_TOKEN" \
  --header 'Accept: application/json'
```

------
#### [ SMART on FHIR ]

SMART 在 FHIR 授权上。授权令牌必须包含`Transaction`资源类型的`read`权限。

```
curl --request GET \
  'https://healthlake.region.amazonaws.com/datastore/datastoreId/r4/Transaction/transactionId' \
  --header 'Authorization: Bearer $SMART_ACCESS_TOKEN' \
  --header 'Accept: application/json'
```

------

下表描述了可能的响应。


**轮询响应码**  

| HTTP 状态 | 含义 | 响应正文 | 
| --- | --- | --- | 
| 202 已接受 | 交易已排队 | OperationOutcome诊断 “已提交” | 
| 202 已接受 | 交易正在处理中 | OperationOutcome诊断 “进行中” | 
| 200 OK (200 确定) | 交易成功完成 | Bundle带类型 transaction-response | 
| 4xx/5xx | 交易失败 | OperationOutcome附有错误详情 | 

以下示例显示了每种响应类型。

**交易已排队 (202)**  


```
{
    "resourceType": "OperationOutcome",
    "id": "transactionId",
    "issue": [
        {
            "severity": "information",
            "code": "informational",
            "diagnostics": "SUBMITTED"
        }
    ]
}
```

**交易处理 (202)**  


```
{
    "resourceType": "OperationOutcome",
    "id": "transactionId",
    "issue": [
        {
            "severity": "information",
            "code": "informational",
            "diagnostics": "IN_PROGRESS"
        }
    ]
}
```

**交易已完成 (200)**  


```
{
    "resourceType": "Bundle",
    "type": "transaction-response",
    "entry": [
        {
            "response": {
                "status": "201",
                "location": "Patient/example-id/_history/1",
                "etag": "W/\"1\"",
                "lastModified": "2024-01-15T10:30:00.000Z"
            }
        },
        {
            "response": {
                "status": "201",
                "location": "Observation/example-id/_history/1",
                "etag": "W/\"1\"",
                "lastModified": "2024-01-15T10:30:00.000Z"
            }
        }
    ]
}
```

**交易失败 (4xx/5xx)**  


```
{
    "resourceType": "OperationOutcome",
    "issue": [
        {
            "severity": "error",
            "code": "exception",
            "diagnostics": "Transaction failed: conflict detected on resource Patient/example-id"
        }
    ]
}
```

### 处理订单
<a name="async-transactions-processing-order"></a>

类型的异步捆绑包`transaction`已排队，但不会按照严格的提交顺序进行处理。 HealthLake 根据可用容量和系统负载优化处理。

**重要**  
不要依赖交易按提交顺序进行处理。例如，如果您在上午 10:00 提交交易 A，在上午 10:01 提交交易 B，则事务 B 可能会在交易 A 之前完成。将您的申请设计为：  
处理 out-of-order完成。
使用轮询网址独立跟踪每笔交易。
如果顺序对您的用例很重要，请实施应用程序级排序。

### 配额和限制
<a name="async-transactions-quotas"></a>

以下配额和速率限制适用于异步交易。


**异步交易配额**  

| 配额 | 值 | 可调整 | 
| --- | --- | --- | 
| 每个异步事务的最大操作数 | 500 | 否 | 
| 每个数据存储的最大待处理事务数 | 500 | 是 | 
+ 异步交易共享中定义的相同 API 速率限制[服务限额](reference-healthlake-endpoints-quotas.md#reference-healthlake-quotas)。
+ 轮询交易状态与 FHIR 资源上的 read (`GET`) 操作具有相同的 API 速率限制。
+ 如果达到待处理交易限额，则后续提交将返回错误，直到现有交易完成。

### 错误处理
<a name="async-transactions-error-handling"></a>

对于 “事务” 捆绑包，捆绑包中包含的所有 FHIR 资源都将作为原子操作进行处理。操作中的所有资源都必须成功，否则不处理捆绑包中的任何操作。

错误分为两类：同步 HealthLake 返回的提交错误和通过轮询检索的处理错误。

**提交错误**  


HealthLake 在提交时验证捆绑包，并在事务排队之前同步返回错误。提交错误包括无效的 FHIR 资源验证错误、不支持的资源类型、超过 500 个操作限制以及将`Prefer: respond-async`标题与批处理捆绑包一起使用。如果已达到数据存储的待处理事务限制，则 HealthLake 返回 a `ThrottlingException`。当发生提交错误时，交易将不会排队。

**处理错误**  


处理错误是在事务排队之后发生的，并通过轮询 URL 返回。其中包括事务冲突，即另一个操作修改了作为事务一部分的资源，以及处理期间的服务器错误。发生处理错误时，不会对事务中的资源进行任何资源变更。轮询网址将返回`OperationOutcome`包含错误详情的。