

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

# 在 中定義增強型訂閱篩選條件 AWS AppSync
<a name="aws-appsync-real-time-enhanced-filtering"></a>

**重要**  
自 2025 年 3 月 13 日起，您可以使用 AWS AppSync Events 建置由 WebSockets 支援的即時 PubSub API。如需詳細資訊，請參閱《AppSync Events 開發人員指南》中的[透過 WebSocket 發佈](https://docs.aws.amazon.com/appsync/latest/eventapi/publish-websocket.html)事件。 *AWS AppSync *

在 中 AWS AppSync，您可以使用支援其他邏輯運算子的篩選條件，直接在 GraphQL API 訂閱解析程式中定義和啟用後端資料篩選的商業邏輯。您可以設定這些篩選條件，與用戶端中訂閱查詢上定義的訂閱引數不同。如需使用訂閱引數的詳細資訊，請參閱 [使用訂閱引數](aws-appsync-real-time-data.md#using-subscription-arguments)。如需運算子清單，請參閱 [AWS AppSync 解析程式映射範本公用程式參考](resolver-util-reference.md)。

基於本文件的目的，我們會將即時資料篩選分為下列類別：
+ **基本篩選** - 根據訂閱查詢中的用戶端定義引數進行篩選。
+ **增強型篩選** - 根據 AWS AppSync 服務後端中集中定義的邏輯進行篩選。

下列各節說明如何設定增強型訂閱篩選條件，並顯示其實際用途。

## 在 GraphQL 結構描述中定義訂閱
<a name="aws-appsync-real-time-enhanced-filtering-using-subscription-filters"></a>

若要使用增強型訂閱篩選條件，請在 GraphQL 結構描述中定義訂閱，然後使用篩選延伸來定義增強型篩選條件。若要說明增強型訂閱篩選的運作方式 AWS AppSync，請使用下列 GraphQL 結構描述，其定義票證管理系統 API，例如：

```
type Ticket {
	id: ID
	createdAt: AWSDateTime
	content: String
	severity: Int
	priority: Priority
	category: String
	group: String
	status: String
	
}

type Mutation {
	createTicket(input: TicketInput): Ticket
}

type Query {
	getTicket(id: ID!): Ticket
}

type Subscription {
	onSpecialTicketCreated: Ticket @aws_subscribe(mutations: ["createTicket"])
	onGroupTicketCreated(group: String!): Ticket @aws_subscribe(mutations: ["createTicket"])
}



enum Priority {
	none
	lowest
	low
	medium
	high
	highest
}

input TicketInput {
	content: String
	severity: Int
	priority: Priority
	category: String
	group: String
```

假設您為 API 建立`NONE`資料來源，然後使用此資料來源將解析程式連接到`createTicket`變動。您的處理常式可能如下所示：

```
import { util } from '@aws-appsync/utils';

export function request(ctx) {
	return {
		payload: {
			id: util.autoId(),
			createdAt: util.time.nowISO8601(),
			status: 'pending',
			...ctx.args.input,
		},
	};
}

export function response(ctx) {
	return ctx.result;
}
```

**注意**  
增強型篩選條件會在指定訂閱的 GraphQL 解析程式處理常式中啟用。如需詳細資訊，請參閱[解析程式參考](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-js-version.html)。

若要實作增強型篩選條件的行為，您必須使用 `extensions.setSubscriptionFilter()`函數來定義篩選條件表達式，根據訂閱用戶端可能感興趣的 GraphQL 變動所發佈的資料進行評估。如需篩選延伸模組的詳細資訊，請參閱[延伸模組](https://docs.aws.amazon.com//appsync/latest/devguide/extensions-js.html)。

下一節說明如何使用篩選延伸來實作增強型篩選條件。

## 使用篩選延伸項目建立增強型訂閱篩選條件
<a name="aws-appsync-real-time-enhanced-filtering-defining-filters"></a>

增強型篩選條件會以 JSON 寫入訂閱解析程式的回應處理常式中。篩選條件可以分組在稱為 的清單中`filterGroup`。篩選條件是使用至少一個規則來定義，每個規則都有欄位、運算子和值。讓我們為 定義新的解析程式`onSpecialTicketCreated`，以設定增強型篩選條件。您可以在使用 AND 邏輯評估的篩選條件中設定多個規則，而篩選群組中的多個篩選條件則使用 OR 邏輯評估：

```
import { util, extensions } from '@aws-appsync/utils';

export function request(ctx) {
	// simplfy return null for the payload
	return { payload: null };
}

export function response(ctx) {
	const filter = {
		or: [
			{ severity: { ge: 7 }, priority: { in: ['high', 'medium'] } },
			{ category: { eq: 'security' }, group: { in: ['admin', 'operators'] } },
		],
	};
	extensions.setSubscriptionFilter(util.transform.toSubscriptionFilter(filter));

  // important: return null in the response
	return null;
}
```

根據上述範例中定義的篩選條件，如果票證是以下列方式建立，則會自動將重要票證推送至訂閱的 API 用戶端：
+ `priority` 關卡`high`或 `medium`

  AND 
+ `severity` 層級大於或等於 `7`(`ge`)

或 
+ `classification` 票證設定為 `Security` 

  AND 
+ `group` 指派設定為 `admin`或 `operators`

![\[顯示票證篩選查詢的範例\]](http://docs.aws.amazon.com/zh_tw/appsync/latest/devguide/images/aws-priority-example.png)


訂閱解析程式中定義的篩選條件 （增強篩選） 優先於僅根據訂閱引數進行篩選 （基本篩選）。如需使用訂閱引數的詳細資訊，請參閱[使用訂閱引數](https://docs.aws.amazon.com//appsync/latest/devguide/aws-appsync-real-time-data.html#using-subscription-arguments))。

如果在訂閱的 GraphQL 結構描述中定義和需要 引數，則只有在引數在解析程式的 `extensions.setSubscriptionFilter()`方法中定義為規則時，才會根據指定的引數進行篩選。不過，如果訂閱解析程式中沒有`extensions`篩選方法，則用戶端中定義的引數只會用於基本篩選。您無法同時使用基本篩選和增強型篩選。

您可以使用訂閱篩選條件延伸邏輯中的 [`context`變數](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-context-reference-js.html)來存取請求的相關內容資訊。例如，使用 Amazon Cognito 使用者集區、OIDC 或 Lambda 自訂授權方進行授權時，您可以在建立訂閱`context.identity`時擷取 中使用者的相關資訊。您可以使用該資訊，根據使用者的身分建立篩選條件。

現在假設您想要實作 的增強型篩選條件行為`onGroupTicketCreated`。`onGroupTicketCreated` 訂閱需要強制`group`名稱做為 引數。建立時，票證會自動指派`pending`狀態。您可以設定訂閱篩選條件，只接收屬於所提供群組的新建立票證：

```
import { util, extensions } from '@aws-appsync/utils';

export function request(ctx) {
	// simplfy return null for the payload
	return { payload: null };
}

export function response(ctx) {
	const filter = { group: { eq: ctx.args.group }, status: { eq: 'pending' } };
	extensions.setSubscriptionFilter(util.transform.toSubscriptionFilter(filter));

	return null;
}
```

使用如下範例中的變動發佈資料時：

```
mutation CreateTicket {
  createTicket(input: {priority: medium, severity: 2, group: "aws"}) {
    id
    priority
    severity
    status
    group
    createdAt
  }
}
```

一旦建立具有`createTicket`變動的票證，訂閱的用戶端就會監聽透過 WebSockets 自動推送的資料：

```
subscription OnGroup {
  onGroupTicketCreated(group: "aws") {
    category
    status
    severity
    priority
    id
    group
    createdAt
    content
  }
}
```

無需引數即可訂閱用戶端，因為篩選邏輯是在 AWS AppSync 服務中使用增強型篩選實作，可簡化用戶端程式碼。只有在符合定義的篩選條件時，用戶端才會接收資料。

## 定義巢狀結構描述欄位的增強型篩選條件
<a name="aws-appsync-real-time-enhanced-filters-nested-schema-fields.title"></a>

您可以使用增強型訂閱篩選來篩選巢狀結構描述欄位。假設我們修改了上一節的結構描述，以包含位置和地址類型：

```
type Ticket {
	id: ID
	createdAt: AWSDateTime
	content: String
	severity: Int
	priority: Priority
	category: String
	group: String
	status: String
	location: ProblemLocation
}

type Mutation {
	createTicket(input: TicketInput): Ticket
}

type Query {
	getTicket(id: ID!): Ticket
}

type Subscription {
	onSpecialTicketCreated: Ticket @aws_subscribe(mutations: ["createTicket"])
	onGroupTicketCreated(group: String!): Ticket @aws_subscribe(mutations: ["createTicket"])
}

type ProblemLocation {
	address: Address
}

type Address {
	country: String
}

enum Priority {
	none
	lowest
	low
	medium
	high
	highest
}

input TicketInput {
	content: String
	severity: Int
	priority: Priority
	category: String
	group: String
	location: AWSJSON
```

透過此結構描述，您可以使用`.`分隔符號來表示巢狀化。下列範例會在 下新增巢狀結構描述欄位的篩選規則`location.address.country`。如果票證的地址設定為 ，則會觸發訂閱`USA`：

```
import { util, extensions } from '@aws-appsync/utils';

export const request = (ctx) => ({ payload: null });

export function response(ctx) {
	const filter = {
		or: [
			{ severity: { ge: 7 }, priority: { in: ['high', 'medium'] } },
			{ category: { eq: 'security' }, group: { in: ['admin', 'operators'] } },
			{ 'location.address.country': { eq: 'USA' } },
		],
	};
	extensions.setSubscriptionFilter(util.transform.toSubscriptionFilter(filter));
	return null;
}
```

在上述範例中， `location`代表巢狀層級一， `address` 代表巢狀層級二， `country`代表巢狀層級三，所有這些都由`.`分隔符號分隔。

您可以使用 `createTicket`變動測試此訂閱：

```
mutation CreateTicketInUSA {
  createTicket(input: {location: "{\"address\":{\"country\":\"USA\"}}"}) {
    category
    content
    createdAt
    group
    id
    location {
      address {
        country
      }
    }
    priority
    severity
    status
  }
}
```

## 從用戶端定義增強型篩選條件
<a name="aws-appsync-real-time-enhanced-filtering-defining-from-client"></a>

您可以在 GraphQL 中使用基本篩選搭配[訂閱引數](https://docs.aws.amazon.com/appsync/latest/devguide/aws-appsync-real-time-data.html#using-subscription-arguments)。在訂閱查詢中進行呼叫的用戶端會定義引數的值。在具有`extensions`篩選條件的 AWS AppSync 訂閱解析程式中啟用增強型篩選條件時，解析程式中定義的後端篩選條件會優先且優先。

使用訂閱中的`filter`引數設定動態、用戶端定義的增強型篩選條件。設定這些篩選條件時，您必須更新 GraphQL 結構描述以反映新引數：

```
...
type Subscription {
    onSpecialTicketCreated(filter: String): Ticket
        @aws_subscribe(mutations: ["createTicket"])
}
...
```

然後，用戶端可以傳送訂閱查詢，如下列範例所示：

```
subscription onSpecialTicketCreated($filter: String) {
     onSpecialTicketCreated(filter: $filter) {
        id
        group
        description
        priority
        severity
     }
 }
```

您可以設定查詢變數，如下列範例所示：

```
{"filter" : "{\"severity\":{\"le\":2}}"}
```

`util.transform.toSubscriptionFilter()` 解析程式公用程式可在訂閱回應映射範本中實作，以套用每個用戶端訂閱引數中定義的篩選條件：

```
import { util, extensions } from '@aws-appsync/utils';

export function request(ctx) {
	// simplfy return null for the payload
	return { payload: null };
}

export function response(ctx) {
	const filter = ctx.args.filter;
	extensions.setSubscriptionFilter(util.transform.toSubscriptionFilter(filter));
	return null;
}
```

透過此策略，用戶端可以定義自己的篩選條件，使用增強型篩選邏輯和其他運算子。當指定的用戶端在安全的 WebSocket 連線中調用訂閱查詢時，會指派篩選條件。如需增強型篩選之轉換公用程式的詳細資訊，包括`filter`查詢變數承載的格式，請參閱 [JavaScript 解析程式概觀](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-overview-js.html)。

## 其他增強型篩選限制
<a name="aws-appsync-real-time-enhanced-filtering-additional-restrictions"></a>

以下是幾個使用案例，其中對增強型篩選條件施加了額外的限制：
+ 增強型篩選條件不支援篩選最上層物件清單。在此使用案例中，增強型訂閱會忽略來自變動的已發佈資料。
+ AWS AppSync 最多支援五個巢狀層級。將忽略巢狀層級 5 以上結構描述欄位的篩選條件。使用以下 GraphQL 回應。`venue.address.country.metadata.continent` 允許 中的 `continent` 欄位，因為它是層級 5 巢狀。不過， `financial` `venue.address.country.metadata.capital.financial`是第六層巢狀，因此篩選條件無法運作：

  ```
  {
      "data": {
          "onCreateFilterEvent": {
              "venue": {
                  "address": {
                      "country": {
                          "metadata": {
                              "capital": {
                                  "financial": "New York"
                              },
                              "continent" : "North America"
                          }
                      },
                      "state": "WA"
                  },
                  "builtYear": 2023
              },
              "private": false,
          }
      }
  }
  ```