

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 設定伺服器端快取和 API 承載壓縮 in AWS AppSync
<a name="enabling-caching"></a>

AWS AppSync的伺服器端資料快取功能可在高速記憶體內快取中提供資料，進而提升效能並減少延遲。這可減少直接存取資料來源的需求。快取適用於單元和管道解析程式。

AWS AppSync 也可讓您壓縮 API 回應，以便更快速地載入和下載承載內容。這可能會降低應用程式的壓力，也可能降低您的資料傳輸費用。壓縮行為是可設定的，您可以自行決定設定。

如需在 AWS AppSync API 中定義伺服器端快取和壓縮所需行為的說明，請參閱本節。

## 執行個體類型
<a name="caching-instances"></a>

AWS AppSync 在與 AWS AppSync API 相同的 AWS 帳戶和 AWS 區域中託管 Amazon ElastiCache (Redis OSS) 執行個體。

下列 ElastiCache (Redis OSS) 執行個體類型可供使用：

**小型**  
1 個 vCPU、1.5 GiB RAM、低到中等網路效能

**中型**  
2 個 vCPU、3 GiB RAM、低到中等網路效能

**大型**  
2 個 vCPU、12.3 GiB RAM、高達 10 GB 的網路效能

**xlarge**  
4 vCPU、25.05 GiB RAM、高達 10 GB 的網路效能

**2xlarge**  
8 個 vCPU、50.47 GiB RAM、高達 10 GB 的網路效能

**4xlarge**  
16 vCPU、101.38 GiB RAM、高達 10 GB 的網路效能

**8xlarge**  
32 vCPU、203.26 GiB RAM、10 Gigabit 網路效能 （並非所有區域都提供）

**12xlarge**  
48 vCPU、317.77 GiB RAM、10 GB 網路效能

**注意**  
過去，您會指定特定的執行個體類型 （例如 `t2.medium`)。截至 2020 年 7 月，這些舊版執行個體類型仍然可用，但其使用已棄用且不建議。我們建議您使用此處所述的一般執行個體類型。

## 快取行為
<a name="caching-behavior"></a>

以下是與快取相關的行為：

**無**  
沒有伺服器端快取。

**完整要求快取**  
完整請求快取是一種個別快取解析程式執行結果的機制。透過此設定， 會 AWS AppSync 快取請求期間叫用的所有解析程式的執行，並個別快取每個解析程式。每個解析程式的資料會從其資料來源擷取，並填入快取，直到存留時間 (TTL) 過期為止。對於後續 API 請求，會從快取傳回每個特定解析程式的結果。這表示除非 TTL 已過期，否則不會直接聯絡資料來源。 AWS AppSync 會使用 的內容，`context.arguments`並將 `context.identity`映射為每個解析程式的快取金鑰。

**每個解析程式快取**  
使用此設定，每個解析程式都必須明確選擇加入，才能快取回應。您可以在解析程式上指定 TTL 和快取金鑰。您可以指定的快取金鑰是來自這些映射的頂層映射 `context.arguments`、 `context.source`和 `context.identity`和/或字串欄位。TTL 值為必填，但快取索引鍵是可選的。如果您未指定任何快取金鑰，預設值為 `context.arguments`、 `context.source`和 `context.identity`映射的內容。  
例如，您可以使用下列組合：  
+ *context.arguments* 和 *context.source*
+ *context.arguments* 和 *context.identity.sub*
+ *context.arguments.id* 或 *context.arguments.InputType.id*
+ *context.source.id* 和 *context.identity.sub*
+ *context.identity.claims.username*
當您僅指定 TTL 且不指定快取金鑰時，解析程式的行為會與完整請求快取相同。

**操作層級快取**  
操作層級快取會將整個 GraphQL 查詢操作回應儲存為整體。啟用時，成功的查詢回應會快取到其 TTL 過期，最大可快取回應大小為 15 MB。對於具有相同快取金鑰的後續查詢請求，回應將直接從快取提供，而不會在 TTL 尚未過期時執行任何解析程式。  
操作層級快取的快取金鑰是使用下列的組合產生：  
+ 來自請求 JSON 承載的特定屬性：
  + `query` 字串
  + `operationName` 字串
  + `variables` 地圖
+ `context.identity` 映射 (IAM 和 Amazon Cognito 請求`context.identity.sourceIp`的 除外）
+ `context.request.headers` 映射 （不包括下一節中列出的特定預留標頭） 
請求所使用的授權類型也會影響快取金鑰。對於 IAM 授權的請求，快取金鑰還會包含允許和拒絕的資源清單。對於 Lambda 授權的請求，快取金鑰還會包含遭拒欄位的清單。  
快取金鑰將考慮 中找到的所有請求標頭`context.request.headers`，但下列預留標頭除外，這些標頭通常對於特定請求是唯一的：  
+ authorization
+ cloudfront-forwarded-proto
+ cloudfront-is-desktop-viewer
+ cloudfront-is-mobile-viewer
+ cloudfront-is-smarttv-viewer
+ cloudfront-is-tablet-viewer
+ cloudfront-viewer-asn
+ cloudfront-viewer-country
+ content-length
+ host
+ priority
+ sec-ch-ua
+ sec-ch-ua-mobile
+ sec-ch-ua-platform
+ via
+ x-amz-cf-id
+ x-amz-date
+ x-amz-security-token
+ x-amzn-appsync-is-vpce-request
+ x-amzn-remote-ip
+ x-amzn-requestid
+ x-amzn-trace-id
+ x-forwarded-for

**快取存留時間**  
此設定定義在記憶體中存放快取項目的時間量。TTL 上限為 3，600 秒 (1 小時），之後會自動刪除項目。

## 快取加密
<a name="caching-encryption"></a>

當您使用 AWS AppSync伺服器端資料快取功能時，靜態和傳輸中的加密一律會針對新快取啟用，且無法停用。

若要在現有 API 快取上啟用加密，請刪除快取，然後重新建立快取。

若要使快取項目失效，您可以使用 AWS AppSync 主控台或 () 進行排清快取 API AWS Command Line Interface 呼叫AWS CLI。

如需詳細資訊，請參閱 AWS AppSync API 參考中的 [ApiCache](https://docs.aws.amazon.com/appsync/latest/APIReference/API_ApiCache.html) 資料類型。

## 快取移出
<a name="cache-eviction-overview"></a>

當您設定 AWS AppSync 的伺服器端快取時，您可以設定最大 TTL。此值定義快取項目儲存在記憶體中的時間量。在您必須從快取移除特定項目的情況下，您可以在解析程式的請求或回應中使用 AWS AppSync 的`evictFromApiCache`延伸公用程式。（例如，當您資料來源中的資料變更，且您的快取項目現在已過時。) 若要從快取中移出項目，您必須知道其金鑰。因此，如果您必須以動態方式移出項目，建議您使用每個解析程式快取，並明確定義要用來將項目新增至快取的金鑰。

## 移出快取項目
<a name="evicting-cache-entries"></a>

若要從快取中移出項目，請使用`evictFromApiCache`延伸項目公用程式。指定類型名稱和欄位名稱，然後提供索引鍵值項目的物件，以建置您要移出之項目的索引鍵。在 物件中，每個金鑰代表快取解析程式`cachingKey`清單中使用之`context`物件的有效項目。每個值都是用來建構金鑰值的實際值。您必須以與快取解析程式`cachingKey`清單中快取金鑰相同的順序，將項目放在物件中。

例如，請參閱下列結構描述：

```
type Note {
  id: ID!
  title: String
  content: String!
}

type Query {
  getNote(id: ID!): Note
}

type Mutation {
  updateNote(id: ID!, content: String!): Note
}
```

在此範例中，您可以啟用每個解析程式快取，然後針對`getNote`查詢啟用它。然後，您可以將快取金鑰設定為包含 `[context.arguments.id]`。

當您嘗試取得 時`Note`，若要建置快取金鑰， AWS AppSync 會使用`getNote`查詢的 `id` 引數在其伺服器端快取中執行查詢。

當您更新 時`Note`，必須移出特定備註的項目，以確保下一個請求從後端資料來源擷取它。若要這樣做，您必須建立請求處理常式。

下列範例顯示使用此方法處理移出的一個方法：

```
import { util, Context } from '@aws-appsync/utils';
import { update } from '@aws-appsync/utils/dynamodb';

export function request(ctx) {
	extensions.evictFromApiCache('Query', 'getNote', { 'ctx.args.id': ctx.args.id });
	return update({ key: { id: ctx.args.id }, update: { context: ctx.args.content } });
}

export const response = (ctx) => ctx.result;
```

或者，您也可以在回應處理常式中處理移出。

處理`updateNote`變動時， AWS AppSync 會嘗試移出項目。如果成功清除項目，回應會在 `extensions` 物件中包含一個`apiCacheEntriesDeleted`值，顯示已刪除的項目數量：

```
"extensions": {  "apiCacheEntriesDeleted": 1}
```

## 根據身分移出快取項目
<a name="evicting-cache-identity"></a>

您可以根據 `context` 物件中的多個值建立快取金鑰。

例如，採用下列結構描述，其使用 Amazon Cognito 使用者集區做為預設身分驗證模式，並由 Amazon DynamoDB 資料來源提供支援：

```
type Note {
  id: ID! # a slug; e.g.: "my-first-note-on-graphql"
  title: String
  content: String!
}

type Query {
  getNote(id: ID!): Note
}

type Mutation {
  updateNote(id: ID!, content: String!): Note
}
```

`Note` 物件類型會儲存在 DynamoDB 資料表中。資料表具有複合索引鍵，使用 Amazon Cognito 使用者名稱做為主索引鍵，並使用 `id`(Slug) `Note`做為分割區索引鍵。這是多租用戶系統，可讓多個使用者託管和更新其私有`Note`物件，而這些物件永遠不會共用。

由於這是一個讀取密集型系統，`getNote`查詢會使用每個解析程式的快取來快取，快取金鑰由 組成`[context.identity.username, context.arguments.id]`。`Note` 更新 時，您可以移出該特定 的項目`Note`。您必須以解析程式`cachingKeys`清單中指定的相同順序，在物件中新增元件。

下列範例顯示：

```
import { util, Context } from '@aws-appsync/utils';
import { update } from '@aws-appsync/utils/dynamodb';

export function request(ctx) {
	extensions.evictFromApiCache('Query', 'getNote', {
		'ctx.identity.username': ctx.identity.username,
		'ctx.args.id': ctx.args.id,
	});
	return update({ key: { id: ctx.args.id }, update: { context: ctx.args.content } });
}

export const response = (ctx) => ctx.result;
```

後端系統也可以更新 `Note`並移出項目。例如，採用此變動：

```
type Mutation {
  updateNoteFromBackend(id: ID!, content: String!, username: ID!): Note @aws_iam
}
```

您可以移出項目，但將快取金鑰的元件新增至`cachingKeys`物件。

在下列範例中，移出發生在解析程式的回應中：

```
import { util, Context } from '@aws-appsync/utils';
import { update } from '@aws-appsync/utils/dynamodb';

export function request(ctx) {
    return update({ key: { id: ctx.args.id }, update: { context: ctx.args.content } });
}

export function response(ctx) {
    extensions.evictFromApiCache('Query', 'getNote', {
        'ctx.identity.username': ctx.args.username,
        'ctx.args.id': ctx.args.id,
    });
    return ctx.result;
}
```

如果您的後端資料已在 AWS AppSync 外部更新，您可以透過呼叫使用`NONE`資料來源的變動，從快取中移出項目。

## 壓縮 API 回應
<a name="api-response-compression"></a>

AWS AppSync 允許用戶端請求壓縮的承載。如果請求，會壓縮並傳回 API 回應，以回應表示偏好壓縮內容的請求。壓縮的 API 回應載入速度更快、內容下載速度更快，而且您的資料傳輸費用也會降低。

**注意**  
壓縮可在 2020 年 6 月 1 日之後建立的所有新 APIs 上使用。  
AWS AppSync 會盡力[壓縮](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/ServingCompressedFiles.html#compressed-content-cloudfront-notes)物件。在極少數情況下， AWS AppSync 可能會根據各種因素略過壓縮，包括目前的容量。

AWS AppSync 可以將 GraphQL 查詢承載大小壓縮在 1，000 到 10，000，000 個位元組之間。若要啟用壓縮，用戶端必須傳送具有值 的 `Accept-Encoding` 標頭`gzip`。您可以透過檢查回應中的`Content-Encoding`標頭值來驗證壓縮 (`gzip`)。

根據預設， AWS AppSync 主控台中的查詢瀏覽器會自動在請求中設定標頭值。如果您執行的查詢有足夠的回應，可以使用瀏覽器開發人員工具來確認壓縮。