

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

# AWS AppSync JavaScript 解析程式內容物件參考
<a name="resolver-context-reference-js"></a>

AWS AppSync 定義了一組變數和函數，用於處理請求和回應處理常式。這樣可讓使用 GraphQL 對資料進行邏輯運算更簡單。本文件說明這些函數並提供範例。

## 正在存取 `context`
<a name="accessing-the-context-js"></a>

請求和回應處理常式的`context`引數是物件，可保留解析程式調用的所有內容資訊。其結構如下：

```
type Context = {
  arguments: any;
  args: any;
  identity: Identity;
  source: any;
  error?: {
    message: string;
    type: string;
  };
  stash: any;
  result: any;
  prev: any;
  request: Request;
  info: Info;
};
```

**注意**  
您通常會發現`context`物件稱為 `ctx`。

`context` 物件中的每個欄位定義如下：

### `context` 欄位
<a name="accessing-the-context-list-js"></a>

** `arguments` **  
包含此欄位所有 GraphQL 引數的映射。

** `identity` **  
包含有關發起人資訊的物件。如需此欄位結構的詳細資訊，請參閱[身分](#aws-appsync-resolver-context-reference-identity-js)。

** `source` **  
包含父欄位解析度的映射。

** `stash` **  
堆疊是在每個解析程式和函數處理常式內提供的物件。相同的 stash 物件透過單一解析程式執行來存留。這表示您可以使用 stash 跨請求和回應處理常式，以及管道解析程式中的函數傳遞任意資料。  
您無法刪除或取代整個停止，但您可以新增、更新、刪除和讀取停止的屬性。
您可以修改下列其中一個程式碼範例，將項目新增至堆疊：  

```
//Example 1
ctx.stash.newItem = { key: "something" }

//Example 2
Object.assign(ctx.stash, {key1: value1, key2: value})
```
您可以修改以下程式碼，從堆疊中移除項目：  

```
delete ctx.stash.key
```

** `result` **  
此解析程式結果的容器。此欄位僅適用於回應處理常式。  
例如，如果您要解決下列查詢`author`的欄位：  

```
query {
    getPost(id: 1234) {
        postId
        title
        content
        author {
            id
            name
        }
    }
}
```
然後，評估回應處理常式時，即可使用完整`context`變數：  

```
{
  "arguments" : {
    id: "1234"
  },
  "source": {},
  "result" : {
      "postId": "1234",
      "title": "Some title",
      "content": "Some content",
      "author": {
        "id": "5678",
        "name": "Author Name"
      }
  },
  "identity" : {
      "sourceIp" : ["x.x.x.x"],
      "userArn" : "arn:aws:iam::123456789012:user/appsync",
      "accountId" : "666666666666",
      "user" : "AIDAAAAAAAAAAAAAAAAAA"
  }
}
```

** `prev.result` **  
在管道解析程式中執行任何先前操作的結果。  
如果先前的操作是管道解析程式的請求處理常式，則 `ctx.prev.result`代表該評估結果，並可供管道中的第一個函數使用。  
如果先前的操作是第一個函數，則 `ctx.prev.result` 代表第一個函數回應處理常式的評估結果，並可供管道中的第二個函數使用。  
如果先前的操作是最後一個函數，則 `ctx.prev.result` 代表最後一個函數的評估結果，並可供管道解析程式的回應處理常式使用。

** `info` **  
包含有關 GraphQL 請求資訊的物件。如需此欄位的結構，請參閱[資訊](#aws-appsync-resolver-context-reference-info-js)。

### Identity
<a name="aws-appsync-resolver-context-reference-identity-js"></a>

包含有關發起人資訊的 `identity` 區段。本節的形狀取決於 AWS AppSync API 的授權類型。

如需 AWS AppSync 安全選項的詳細資訊，請參閱[授權和身分驗證](security-authz.md#aws-appsync-security)。

** `API_KEY` 授權**  
`identity` 欄位未填入。

**`AWS_LAMBDA` 授權**  
`identity` 的格式如下：  

```
type AppSyncIdentityLambda = {
  resolverContext: any;
};
```
`identity` 包含 `resolverContext`金鑰，其中包含由授權請求的 Lambda 函數傳回的相同`resolverContext`內容。

** `AWS_IAM` 授權**  
`identity` 的格式如下：  

```
type AppSyncIdentityIAM = {
  accountId: string;
  cognitoIdentityPoolId: string;
  cognitoIdentityId: string;
  sourceIp: string[];
  username: string;
  userArn: string;
  cognitoIdentityAuthType: string;
  cognitoIdentityAuthProvider: string;
};
```

** `AMAZON_COGNITO_USER_POOLS` 授權**  
`identity` 的格式如下：  

```
type AppSyncIdentityCognito = {
  sourceIp: string[];
  username: string;
  groups: string[] | null;
  sub: string;
  issuer: string;
  claims: any;
  defaultAuthStrategy: string;
};
```

每個欄位的定義如下：

** `accountId` **  
發起人 AWS 的帳戶 ID。

** `claims` **  
使用者擁有的宣告。

** `cognitoIdentityAuthType` **  
經身分驗證或未經身分驗證 (根據身分類型)。

** `cognitoIdentityAuthProvider` **  
以逗號分隔的外部身分提供者資訊清單，用於取得用於簽署請求的登入資料。

** `cognitoIdentityId` **  
發起人的 Amazon Cognito 身分 ID。

** `cognitoIdentityPoolId` **  
與發起人相關聯的 Amazon Cognito 身分集區 ID。

** `defaultAuthStrategy` **  
此發起人 (`ALLOW` 或 `DENY`) 的預設授權策略。

** `issuer` **  
字符發行者。

** `sourceIp` **  
 AWS AppSync 接收的發起人的來源 IP 地址。如果請求不包含 `x-forwarded-for`標頭，來源 IP 值只會包含來自 TCP 連線的單一 IP 地址。如果要求包含 `x-forwarded-for` 標頭，則來源 IP 除了有 TCP 連線的 IP 地址外，也將有 `x-forwarded-for` 標頭中 IP 地址的清單。

** `sub` **  
已驗證使用者的 UUID。

** `user` **  
IAM 使用者。

** `userArn` **  
IAM 使用者的 Amazon Resource Name (ARN)。

** `username` **  
已驗證使用者的使用者名稱。如果是 `AMAZON_COGNITO_USER_POOLS` 授權，*使用者名稱*的值是屬性 *cognito:username* 的值。在`AWS_IAM`授權的情況下，*使用者名稱*的值是 AWS 使用者主體的值。如果您使用 IAM 授權搭配來自 Amazon Cognito 身分集區的憑證，我們建議您使用 `cognitoIdentityId`。

### 存取請求標頭
<a name="aws-appsync-resolver-context-reference-util-js"></a>

AWS AppSync 支援從用戶端傳遞自訂標頭，並使用 在 GraphQL 解析程式中存取它們`ctx.request.headers`。然後，您可以將 標頭值用於動作，例如將資料插入資料來源或授權檢查。您可以將 與來自命令列的 API 金鑰`$curl`搭配使用的單一或多個請求標頭，如下列範例所示：

**單一標頭範例** 

假設您設定使用 `custom` 值的 `nadia` 標頭，如下所示：

```
curl -XPOST -H "Content-Type:application/graphql" -H "custom:nadia" -H "x-api-key:<API-KEY-VALUE>" -d '{"query":"mutation { createEvent(name: \"demo\", when: \"Next Friday!\", where: \"Here!\") {id name when where description}}"}' https://<ENDPOINT>/graphql
```

可使用 `ctx.request.headers.custom` 對此進行存取。例如，它可能位於 DynamoDB 的下列程式碼中：

```
"custom": util.dynamodb.toDynamoDB(ctx.request.headers.custom)
```

**多個標頭範例** 

您也可以在單一請求中傳遞多個標頭，並在解析程式處理常式中存取這些標頭。例如，如果 `custom`標頭設定為兩個值：

```
curl -XPOST -H "Content-Type:application/graphql" -H "custom:bailey" -H "custom:nadia" -H "x-api-key:<API-KEY-VALUE>" -d '{"query":"mutation { createEvent(name: \"demo\", when: \"Next Friday!\", where: \"Here!\") {id name when where description}}"}' https://<ENDPOINT>/graphql
```

然後，您可以將這些存取為陣列，例如 `ctx.request.headers.custom[1]`。

**注意**  
AWS AppSync 不會在 中公開 Cookie 標頭`ctx.request.headers`。

### 存取請求自訂網域名稱
<a name="aws-access-requested-custom-domain-names-js"></a>

AWS AppSync 支援設定自訂網域，您可以用來存取 APIs的 GraphQL 和即時端點。使用自訂網域名稱提出請求時，您可以使用 取得網域名稱`ctx.request.domainName`。

使用預設 GraphQL 端點網域名稱時，值為 `null`。

### 資訊
<a name="aws-appsync-resolver-context-reference-info-js"></a>

`info` 區段包含有關 GraphQL 請求的資訊。本節的格式如下：

```
type Info = {
  fieldName: string;
  parentTypeName: string;
  variables: any;
  selectionSetList: string[];
  selectionSetGraphQL: string;
};
```

每個欄位的定義如下：

** `fieldName` **  
目前正在解析的欄位名稱。

** `parentTypeName` **  
目前正在解析的欄位父類型名稱。

** `variables` **  
包含傳遞給 GraphQL 請求之所有變數的映射。

** `selectionSetList` **  
此清單表示 GraphQL 選取範圍中的欄位。別名的欄位僅由別名名稱參考，而非欄位名稱。以下範例詳細說明這一點。

** `selectionSetGraphQL` **  
此字串表示格式為 GraphQL 結構描述定義語言 (SDL) 的選取範圍。雖然片段不會合併到選取集，但會保留內嵌片段，如下列範例所示。

**注意**  
`JSON.stringify` 不會在字串序列化`selectionSetList`中包含 `selectionSetGraphQL`和 。您必須直接參考這些屬性。

例如，如果您解析下列查詢的 `getPost` 欄位：

```
query {
  getPost(id: $postId) {
    postId
    title
    secondTitle: title
    content
    author(id: $authorId) {
      authorId
      name
    }
    secondAuthor(id: "789") {
      authorId
    }
    ... on Post {
      inlineFrag: comments: {
        id
      }
    }
    ... postFrag
  }
}

fragment postFrag on Post {
  postFrag: comments: {
    id
  }
}
```

然後，處理處理常式時可用的完整`ctx.info`變數可能是：

```
{
  "fieldName": "getPost",
  "parentTypeName": "Query",
  "variables": {
    "postId": "123",
    "authorId": "456"
  },
  "selectionSetList": [
    "postId",
    "title",
    "secondTitle"
    "content",
    "author",
    "author/authorId",
    "author/name",
    "secondAuthor",
    "secondAuthor/authorId",
    "inlineFragComments",
    "inlineFragComments/id",
    "postFragComments",
    "postFragComments/id"
  ],
  "selectionSetGraphQL": "{\n  getPost(id: $postId) {\n    postId\n    title\n    secondTitle: title\n    content\n    author(id: $authorId) {\n      authorId\n      name\n    }\n    secondAuthor(id: \"789\") {\n      authorId\n    }\n    ... on Post {\n      inlineFrag: comments {\n        id\n      }\n    }\n    ... postFrag\n  }\n}"
}
```

`selectionSetList` 只會公開屬於目前類型的欄位。如果目前類型是界面或聯集，則只會公開屬於界面的所選欄位。例如，指定下列結構描述：

```
type Query {
    node(id: ID!): Node
}

interface Node {
    id: ID
}

type Post implements Node {
    id: ID
    title: String
    author: String
}

type Blog implements Node {
    id: ID
    title: String
    category: String
}
```

以及下列查詢：

```
query {
    node(id: "post1") {
        id
        ... on Post {
            title
        }

        ... on Blog {
            title
        }
    }
}
```

`ctx.info.selectionSetList` 以`Query.node`欄位解析度呼叫 時，只會`id`公開：

```
"selectionSetList": [
    "id"
]
```