

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

# AWS AppSync JavaScript visão geral dos resolvedores
<a name="resolver-reference-overview-js"></a>

AWS AppSync permite que você responda às solicitações do GraphQL executando operações em suas fontes de dados. Para cada campo do GraphQL em que você deseja executar uma consulta, mutação ou assinatura, um resolvedor deve ser anexado.

Os resolvedores são os conectores entre o GraphQL e uma fonte de dados. Eles explicam AWS AppSync como traduzir uma solicitação recebida do GraphQL em instruções para sua fonte de dados de back-end e como traduzir a resposta dessa fonte de dados em uma resposta do GraphQL. Com AWS AppSync, você pode escrever seus resolvedores usando JavaScript e executá-los no ambiente AWS AppSync (`APPSYNC_JS`). 

AWS AppSync permite escrever resolvedores de unidades ou resolvedores de pipeline compostos por várias AWS AppSync funções em um pipeline.

## Atributos compatíveis de runtime
<a name="runtime-support-js"></a>

O AWS AppSync JavaScript tempo de execução fornece um subconjunto de JavaScript bibliotecas, utilitários e recursos. Para obter uma lista completa dos recursos e funcionalidades suportados pelo tempo de `APPSYNC_JS` execução, consulte [recursos JavaScript de tempo de execução para resolvedores e funções](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-util-reference-js.html).

## Resolvedores de unidade
<a name="unit-resolver-js"></a>

Um resolvedor de unidade é composto de código que define um único manipulador de solicitação e resposta que é executado em uma fonte de dados. O manipulador da solicitação usa um objeto de contexto como argumento e retorna o payload da solicitação usado para chamar sua fonte de dados. O manipulador de respostas recebe uma payload da fonte de dados com o resultado da solicitação executada. O manipulador de resposta transforma o payload em uma resposta do GraphQL para resolver o campo GraphQL. No exemplo abaixo, um resolvedor recupera um item de uma fonte de dados do DynamoDB:

```
import * as ddb from '@aws-appsync/utils/dynamodb'

export function request(ctx) {
  return ddb.get({ key: { id: ctx.args.id } });
}

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

## Anatomia de um resolvedor de JavaScript pipeline
<a name="anatomy-of-a-pipeline-resolver-js"></a>

Um resolvedor de pipeline é composto de código que define um manipulador de solicitação e resposta e uma lista de funções. Cada função possui um manipulador de **solicitação** e **resposta** que é executado em uma fonte de dados. Como um resolvedor de pipeline delega a execução a uma lista de funções, ele não está vinculado a nenhuma fonte de dados. Os resolvedores de unidade e funções que executam a operação mediante fontes de dados são primitivos.

### Manipulador de solicitações do resolvedor de pipeline
<a name="request-handler-js"></a>

O manipulador de solicitação de um resolvedor de pipeline, ou etapa Anterior, permite executar uma lógica de preparação antes de executar as funções definidas.

### Lista de funções
<a name="functions-list-js"></a>

A lista de funções que um resolvedor de pipeline executará em sequência. O resultado do manipulador da solicitação do resolvedor de pipeline é disponibilizado para a primeira função como `ctx.prev.result`. Cada resultado da avaliação da função está disponível para a próxima função como `ctx.prev.result`.

### Manipulador de resposta do resolvedor de pipeline
<a name="response-handler-js"></a>

O modelo de resposta de um resolvedor de pipeline permite executar uma lógica final na saída da última função para o tipo de campo do GraphQL esperado. A saída da última função na lista de funções está disponível no manipulador de resposta do resolvedor de pipeline, como `ctx.prev.result` ou `ctx.result`.

### Fluxo de execução
<a name="execution-flow-js"></a>

Considerando um resolvedor de pipeline composto de duas funções, a lista abaixo representa o fluxo de execução quando o resolvedor é invocado:

1.  Manipulador de solicitações do resolvedor de pipeline

1.  Função 1: manipulador de solicitação de função 

1.  Função 1: invocação da fonte de dados 

1.  Função 1: manipulador de resposta de função 

1.  Função 2: manipulador de solicitação de função 

1.  Função 2: invocação da fonte de dados 

1.  Função 2: manipulador de resposta de função 

1.  Manipulador de resposta do resolvedor de pipeline 

![\[GraphQL request flow diagram showing interactions between request, data sources, and response components.\]](http://docs.aws.amazon.com/pt_br/appsync/latest/devguide/images/appsync-js-resolver-logic.png)


### Utilitários integrados úteis do runtime `APPSYNC_JS`
<a name="useful-utilities-js"></a>

Os utilitários a seguir podem ajudá-lo quando você estiver trabalhando com resolvedores de pipeline.

#### ctx.stash
<a name="ctx-stash-js"></a>

O stash é um objeto disponibilizado dentro de cada manipulador de resposta e solicitação de resolvedor e função. A mesma instância stash passa por uma única execução do resolvedor. Isso significa que é possível usar o stash para enviar dados arbitrários entre os manipuladores de solicitações e respostas e entre as funções em um resolvedor de pipeline. Você pode testar o estoque como um JavaScript objeto normal.

#### ctx.prev.result
<a name="ctx-prev-result-js"></a>

O `ctx.prev.result` representa o resultado da operação anterior que foi executada no pipeline. Se a operação anterior foi o manipulador de solicitações do resolvedor de pipeline, `ctx.prev.result` será disponibilizado para a primeira função no encadeamento. Se a operação anterior foi a primeira função, `ctx.prev.result` representa a saída da primeira função e será disponibilizado para a segunda função no pipeline. Se a operação anterior foi a última função, `ctx.prev.result` representa a saída da última função e será disponibilizado para o manipulador de resposta do resolvedor de pipeline.

#### util.error
<a name="util-error-js"></a>

O utilitário `util.error` é útil para gerar um erro de campo. Usar `util.error` dentro de um manipulador de solicitação ou resposta de função gera um erro de campo imediatamente, o que impede que funções subsequentes sejam executadas. Para obter mais detalhes e outras `util.error` assinaturas, visite [recursos de JavaScript tempo de execução para resolvedores e](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-util-reference-js.html) funções.

#### util.appendError
<a name="util-appenderror-js"></a>

O `util.appendError` é semelhante a `util.error()`, com a principal distinção de que ele não interrompe a avaliação do manipulador. Em vez disso, ele sinaliza que ocorreu um erro com o campo, mas permite que o manipulador seja avaliado e, consequentemente, retorne dados. Usar `util.appendError` dentro de uma função não interromperá o fluxo de execução do pipeline. Para obter mais detalhes e outras `util.error` assinaturas, visite os [recursos de JavaScript tempo de execução para resolvedores e](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-util-reference-js.html) funções.

#### runtime.earlyReturn
<a name="runtime-earlyreturn-js"></a>

A função `runtime.earlyReturn` permite que você gere resultados prematuramente para qualquer função de solicitação. Usar `runtime.earlyReturn` em um manipulador de solicitações do resolvedor retornará resultados do resolvedor. Chamá-lo em um manipulador de solicitação de função AWS AppSync retornará resultados a partir da função e continuará a execução até a próxima função no pipeline ou o manipulador de resposta do resolvedor.

### Escrever resolvedores de pipeline
<a name="writing-resolvers"></a>

Um resolvedor de pipeline também tem um manipulador de solicitação e resposta para a execução das funções no pipeline: o manipulador de solicitação é executado antes da solicitação da primeira função, e o manipulador de resposta é executado após a resposta da última função. O manipulador de solicitação do resolvedor pode configurar dados para serem usados pelas funções no pipeline. O manipulador de resposta do resolvedor é responsável por retornar dados que são mapeados para o tipo de saída do campo GraphQL. No exemplo abaixo, um manipulador de solicitação do resolvedor define `allowedGroups`; os dados retornados devem pertencer a um desses grupos. Esse valor pode ser usado pelas funções do resolvedor para solicitar dados. O manipulador de resposta do resolvedor realiza uma verificação final e filtra o resultado para garantir que somente os itens que pertencem aos grupos permitidos sejam retornados.

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

/**
 * Called before the request function of the first AppSync function in the pipeline.
 *  @param ctx the context object holds contextual information about the function invocation.
 */
export function request(ctx) {
  ctx.stash.allowedGroups = ['admin'];
  ctx.stash.startedAt = util.time.nowISO8601();
  return {};
}
/**
 * Called after the response function of the last AppSync function in the pipeline.
 * @param ctx the context object holds contextual information about the function invocation.
 */
export function response(ctx) {
  const result = [];
  for (const item of ctx.prev.result) {
    if (ctx.stash.allowedGroups.indexOf(item.group) > -1) result.push(item);
  }
  return result;
}
```

#### AWS AppSync Funções de escrita
<a name="writing-functions"></a>

AWS AppSync as funções permitem que você escreva uma lógica comum que você pode reutilizar em vários resolvedores em seu esquema. Por exemplo, você pode ter uma AWS AppSync função chamada `QUERY_ITEMS` responsável por consultar itens de uma fonte de dados do Amazon DynamoDB. Para resolvedores com os quais você gostaria de consultar itens, basta adicionar a função ao pipeline do resolvedor e fornecer o índice de consulta a ser usado. A lógica não precisa ser reimplementada.

## Tópicos complementares
<a name="supplemental-topics"></a>

**Tópicos**
+ [Exemplo de resolvedor de pipeline com o Amazon DynamoDB](https://docs.aws.amazon.com/appsync/latest/devguide/writing-code.html)
+ [Configuração de utilitários para o runtime do `APPSYNC_JS`](https://docs.aws.amazon.com/appsync/latest/devguide/utility-resolvers.html)
+ [Agrupamento e mapas TypeScript de origem para o tempo de execução `APPSYNC_JS`](https://docs.aws.amazon.com/appsync/latest/devguide/additional-utilities.html)
+ [Como testar seu resolvedor e manipuladores de função](https://docs.aws.amazon.com/appsync/latest/devguide/test-resolvers.html)
+ [Migrando da VTL para JavaScript](https://docs.aws.amazon.com/appsync/latest/devguide/migrating-resolvers.html)
+ [Escolha entre acesso direto à fonte de dados e proxy por meio de uma fonte de dados do Lambda](https://docs.aws.amazon.com/appsync/latest/devguide/choosing-data-source.html)

# Exemplo de resolvedor de pipeline com o Amazon DynamoDB
<a name="writing-code"></a>

Digamos que você queira anexar um resolvedor de pipeline em um campo chamado `getPost(id:ID!)` que retorna o tipo `Post` de uma fonte de dados do Amazon DynamoDB com a seguinte consulta do GraphQL:

```
getPost(id:1){
    id
    title
    content
}
```

Primeiro, anexe um resolvedor simples a `Query.getPost` com o código abaixo. Este é um exemplo de código de resolvedor simples. Não há lógica definida no manipulador de solicitação, e o manipulador de resposta simplesmente retorna o resultado da última função.

```
/**
 * Invoked **before** the request handler of the first AppSync function in the pipeline.
 * The resolver `request` handler allows to perform some preparation logic
 * before executing the defined functions in your pipeline.
 * @param ctx the context object holds contextual information about the function invocation.
 */
export function request(ctx) {
  return {}
}

/**
 * Invoked **after** the response handler of the last AppSync function in the pipeline.
 * The resolver `response` handler allows to perform some final evaluation logic
 * from the output of the last function to the expected GraphQL field type.
 * @param ctx the context object holds contextual information about the function invocation.
 */
export function response(ctx) {
  return ctx.prev.result
}
```

Em seguida, defina a função `GET_ITEM` que recupera um postItem da sua fonte de dados:

```
import { util } from '@aws-appsync/utils'
import * as ddb from '@aws-appsync/utils/dynamodb'

/**
 * Request a single item from the attached DynamoDB table datasource
 * @param ctx the context object holds contextual information about the function invocation.
 */
export function request(ctx) {
	const { id } = ctx.args
	return ddb.get({ key: { id } })
}

/**
 * Returns the result
 * @param ctx the context object holds contextual information about the function invocation.
 */
export function response(ctx) {
	const { error, result } = ctx
	if (error) {
		return util.appendError(error.message, error.type, result)
	}
	return ctx.result
}
```

Se houver um erro durante a solicitação, o manipulador de resposta da função anexará no final um erro que será retornado ao cliente chamador na resposta do GraphQL. Adicione a função `GET_ITEM` à sua lista de funções do resolvedor. Quando você executa a consulta, o manipulador de solicitações da `GET_ITEM` função usa os utilitários fornecidos pelo módulo AWS AppSync DynamoDB para criar uma `DynamoDBGetItem` solicitação usando o como chave. `id` `ddb.get({ key: { id } })`gera a `GetItem` operação apropriada:

```
{
    "operation" : "GetItem",
    "key" : {
        "id" : { "S" : "1" }
    }
}
```

AWS AppSync usa a solicitação para buscar os dados do Amazon DynamoDB. Depois que os dados são retornados, eles são tratados pelo manipulador de resposta da função `GET_ITEM`, que verifica erros e retorna o resultado. 

```
{
  "result" : {
    "id": 1,
    "title": "hello world",
    "content": "<long story>"
  }
}
```

Finalmente, o manipulador de resposta do resolvedor retorna o resultado diretamente.

## Como trabalhar com eventos
<a name="working-with-errors"></a>

Se ocorrer um erro na sua função durante uma solicitação, ele será disponibilizado no manipulador de resposta da função em `ctx.error`. Você pode acrescentar o erro no final da sua resposta do GraphQL usando o utilitário `util.appendError`. É possível disponibilizar o erro para outras funções no pipeline usando o stash. Veja o exemplo abaixo:

```
/**
 * Returns the result
 * @param ctx the context object holds contextual information about the function invocation.
 */
export function response(ctx) {
  const { error, result } = ctx;
  if (error) {
    if (!ctx.stash.errors) ctx.stash.errors = []
    ctx.stash.errors.push(ctx.error)
    return util.appendError(error.message, error.type, result);
  }
  return ctx.result;
}
```

# Configuração de utilitários para o runtime do `APPSYNC_JS`
<a name="utility-resolvers"></a>

AWS AppSync fornece duas bibliotecas que auxiliam no desenvolvimento de resolvedores com o `APPSYNC_JS` tempo de execução: 
+ `@aws-appsync/eslint-plugin`: detecta e corrige problemas rapidamente durante o desenvolvimento.
+ `@aws-appsync/utils`: fornece validação de tipo e preenchimento automático em editores de código.

## Configurar o plug-in eslint
<a name="utility-resolvers-configuring-eslint-plugin"></a>

[ESLint](https://eslint.org/)é uma ferramenta que analisa estaticamente seu código para encontrar problemas rapidamente. Você pode executar ESLint como parte do seu pipeline de integração contínua. `@aws-appsync/eslint-plugin`é um ESLint plug-in que captura a sintaxe inválida em seu código ao aproveitar o tempo de execução. `APPSYNC_JS` O plug-in permite que você receba rapidamente feedback sobre seu código durante o desenvolvimento sem precisar enviar suas alterações para a nuvem.

`@aws-appsync/eslint-plugin` fornece dois conjuntos de regras que você pode usar durante o desenvolvimento. 

**“plugin:@aws-appsync/base”** configura um conjunto básico de regras que você pode aproveitar no seu projeto: 


| Rule | Description | 
| --- | --- | 
| no-async | Promessas e processos assíncronos não são compatíveis. | 
| no-await | Promessas e processos assíncronos não são compatíveis. | 
| no-classes | Classes não são compatíveis. | 
| no-for | for não é compatível (exceto para for-in e for-of, que são aceitos) | 
| no-continue | Não há suporte ao continue. | 
| no-generators | Geradores não são compatíveis. | 
| no-yield | Não há suporte ao yield. | 
| no-labels | Rótulos não são compatíveis. | 
| no-this | A palavra-chave this não é compatível. | 
| no-try | A estrutura try/catch não é compatível. | 
| no-while | Loops While não são compatíveis. | 
| no-disallowed-unary-operators | Operadores unários \$1\$1, -- e \$1 não são compatíveis. | 
| no-disallowed-binary-operators | O operador instanceof não é compatível. | 
| no-promise | Promessas e processos assíncronos não são compatíveis. | 

**“plugin: @aws -appsync/recommended”** fornece algumas regras adicionais, mas também exige que você adicione TypeScript configurações ao seu projeto.


| Rule | Description | 
| --- | --- | 
| no-recursion | Chamadas de função recursivas não são compatíveis | 
| no-disallowed-methods | Alguns métodos não são compatíveis. Consulte a [referência](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-util-reference-js.html) para obter um conjunto completo de funções integradas compatíveis. | 
| no-function-passing | Não é permitido enviar funções como argumentos de função para funções. | 
| no-function-reassign | As funções não podem ser reatribuídas. | 
| no-function-return | As funções não podem ser o valor de retorno das funções. | 

Para adicionar o plug-in ao seu projeto, siga as etapas de instalação e uso em [Introdução ao ESLint](https://eslint.org/docs/latest/user-guide/getting-started#installation-and-usage). Em seguida, instale o [plug-in](https://www.npmjs.com/package/@aws-appsync/eslint-plugin) no seu projeto usando o gerenciador de pacotes do projeto (por exemplo, npm, yarn ou pnpm):

```
$ npm install @aws-appsync/eslint-plugin
```

No seu arquivo `.eslintrc.{js,yml,json}`, adicione **“plugin:@aws-appsync/base”** ou **“plugin:@aws-appsync/recommended**” à propriedade `extends`. O trecho abaixo é um exemplo básico de `.eslintrc` configuração para: JavaScript 

```
{
  "extends": ["plugin:@aws-appsync/base"]
}
```

Para usar o conjunto de regras **“plugin:@aws-appsync/recommended”**, instale a dependência necessária:

```
$ npm install -D @typescript-eslint/parser
```

Depois, crie um arquivo `.eslintrc.js`:

```
{
  "parser": "@typescript-eslint/parser",
  "parserOptions": {
    "ecmaVersion": 2018,
    "project": "./tsconfig.json"
  },
  "extends": ["plugin:@aws-appsync/recommended"]
}
```

# Agrupamento e mapas TypeScript de origem para o tempo de execução `APPSYNC_JS`
<a name="additional-utilities"></a>

TypeScript aprimora AWS AppSync o desenvolvimento fornecendo segurança de tipo e detecção precoce de erros. Você pode escrever TypeScript código localmente e transpilá-lo JavaScript antes de usá-lo com o `APPSYNC_JS` tempo de execução. O processo começa com a instalação TypeScript e configuração do tsconfig.json para o ambiente. `APPSYNC_JS` Em seguida, é possível utilizar ferramentas de empacotamento, como a esbuild, para compilar e empacotar o código. A CLI do Amplify gerará tipos do esquema GraphQL, permitindo que você use esses tipos no código do resolvedor. 

No seu resolvedor e código de função, você pode aproveitar bibliotecas personalizadas e externas, desde que estejam em conformidade com os requisitos do `APPSYNC_JS`. As ferramentas de agrupamento combinam código em um único arquivo para uso em AWS AppSync. Os mapas de origem podem ser incluídos para ajudar na depuração. 

## Aproveitar as bibliotecas e empacotar seu código
<a name="using-external-libraries"></a>

No seu resolvedor e código de função, você pode aproveitar bibliotecas personalizadas e externas, desde que estejam em conformidade com os requisitos de `APPSYNC_JS`. Isso possibilita a reutilização do código existente na sua aplicação. Para usar bibliotecas definidas por vários arquivos, você deve usar uma ferramenta de agrupamento, como [esbuild](https://esbuild.github.io/), para combinar seu código em um único arquivo que pode ser salvo em seu AWS AppSync resolvedor ou função.

Ao empacotar o código, lembre-se do seguinte:
+ `APPSYNC_JS`suporta apenas ECMAScript módulos (ESM).
+ Os módulos `@aws-appsync/*` são integrados em `APPSYNC_JS` e não devem ser empacotados com seu código.
+ O ambiente de runtime `APPSYNC_JS` é semelhante ao NodeJS, pois o código não é executado em um ambiente de navegador.
+ Você pode incluir um mapa de origem opcional. No entanto, não inclua o conteúdo original.

  Para saber mais sobre mapas de origem, consulte [Usar mapas de origem](#source-maps).

Por exemplo, para empacotar o código do resolvedor localizado em `src/appsync/getPost.resolver.js`, é possível usar o seguinte comando CLI esbuild:

```
$ esbuild --bundle \
--sourcemap=inline \
--sources-content=false \
--target=esnext \
--platform=node \
--format=esm \
--external:@aws-appsync/utils \
--outdir=out/appsync \
 src/appsync/getPost.resolver.js
```

## Criando seu código e trabalhando com TypeScript
<a name="working-with-typescript"></a>

[TypeScript](https://www.typescriptlang.org/)é uma linguagem de programação desenvolvida pela Microsoft que oferece todos os JavaScript recursos junto com o sistema de TypeScript digitação. Você pode usar TypeScript para escrever código de tipo seguro e capturar erros e bugs no momento da compilação antes de salvar seu código no. AWS AppSync O pacote `@aws-appsync/utils` está totalmente inserido.

O `APPSYNC_JS` tempo de execução não oferece suporte TypeScript direto. Primeiro, você deve transpilar seu TypeScript código para um JavaScript código compatível com o `APPSYNC_JS` tempo de execução antes de salvá-lo. AWS AppSync Você pode usar TypeScript para escrever seu código em seu ambiente de desenvolvimento integrado (IDE) local, mas observe que você não pode criar TypeScript código no AWS AppSync console.

Para começar, verifique se você [TypeScript](https://www.typescriptlang.org/download)instalou em seu projeto. Em seguida, defina suas configurações de TypeScript transcompilação para trabalhar com o `APPSYNC_JS` tempo de execução usando. [TSConfig](https://www.typescriptlang.org/tsconfig) Aqui está um exemplo de um arquivo básico `tsconfig.json` que você pode usar:

```
// tsconfig.json
{
  "compilerOptions": {
    "target": "esnext",
    "module": "esnext",
   "noEmit": true,
   "moduleResolution": "node",
  }
}
```

Em seguida, é possível utilizar uma ferramenta de empacotamento como esbuild para compilar e agrupar seu código. Por exemplo, em um projeto com seu AWS AppSync código localizado em`src/appsync`, você pode usar o comando a seguir para compilar e agrupar seu código:

```
$ esbuild --bundle \
--sourcemap=inline \
--sources-content=false \
--target=esnext \
--platform=node \
--format=esm \
--external:@aws-appsync/utils \
--outdir=out/appsync \
 src/appsync/**/*.ts
```

### Usar o codegen Amplify
<a name="working-with-amplify-codegen"></a>

Você pode usar a [CLI do Amplify](https://docs.amplify.aws/cli/) para gerar os tipos para seu esquema. No diretório em que seu arquivo `schema.graphql` está localizado, execute o comando a seguir e revise os prompts para configurar seu codegen:

```
$  npx @aws-amplify/cli codegen add
```

Para regenerar seu codegen em determinadas circunstâncias (por exemplo, quando seu esquema é atualizado), execute o seguinte comando:

```
$ npx @aws-amplify/cli codegen
```

Em seguida, é possível usar os tipos gerados no código do resolvedor. Por exemplo, considerando o seguinte esquema:

```
type Todo {
  id: ID!
  title: String!
  description: String
}

type Mutation {
  createTodo(title: String!, description: String): Todo
}

type Query {
  listTodos: Todo
}
```

Você pode usar os tipos gerados na seguinte AWS AppSync função de exemplo:

```
import { Context, util } from '@aws-appsync/utils'
import * as ddb from '@aws-appsync/utils/dynamodb'
import { CreateTodoMutationVariables, Todo } from './API' // codegen

export function request(ctx: Context<CreateTodoMutationVariables>) {
	ctx.args.description = ctx.args.description ?? 'created on ' + util.time.nowISO8601()
	return ddb.put<Todo>({ key: { id: util.autoId() }, item: ctx.args })
}

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

### Usando genéricos em TypeScript
<a name="working-with-typescript-generics"></a>

Você pode usar genéricos com vários dos tipos fornecidos. Por exemplo, o trecho abaixo é do tipo `Todo`:

```
export type Todo = {
  __typename: "Todo",
  id: string,
  title: string,
  description?: string | null,
};
```

Você pode escrever um resolvedor para uma assinatura que use `Todo`. No seu IDE, as definições de tipo e as dicas de preenchimento automático orientarão você a usar corretamente o utilitário de transformação `toSubscriptionFilter`:

```
import { util, Context, extensions } from '@aws-appsync/utils'
import { Todo } from './API'

export function request(ctx: Context) {
  return {}
}

export function response(ctx: Context) {
  const filter = util.transform.toSubscriptionFilter<Todo>({
    title: { beginsWith: 'hello' },
    description: { contains: 'created' },
  })
  extensions.setSubscriptionFilter(filter)
  return null
}
```

## Usar Lint nos seus pacotes
<a name="using-lint-with-bundles"></a>

Você pode filtrar automaticamente seus pacotes importando o plug-in `esbuild-plugin-eslint`. Em seguida, você pode ativá-lo fornecendo um valor `plugins` que ative os recursos do eslint. Abaixo está um trecho que usa a JavaScript API esbuild em um arquivo chamado: `build.mjs`

```
/* eslint-disable */
import { build } from 'esbuild'
import eslint from 'esbuild-plugin-eslint'
import glob from 'glob'
const files = await glob('src/**/*.ts')

await build({
  format: 'esm',
  target: 'esnext',
  platform: 'node',
  external: ['@aws-appsync/utils'],
  outdir: 'dist/',
  entryPoints: files,
  bundle: true,
  plugins: [eslint({ useEslintrc: true })],
})
```

## Usar mapas de origem
<a name="source-maps"></a>

Você pode fornecer um mapa de origem embutido (`sourcemap`) com seu JavaScript código. Os mapas de origem são úteis para quando você agrupa JavaScript ou TypeScript codifica e deseja ver referências aos seus arquivos de origem de entrada em seus registros e mensagens de JavaScript erro de tempo de execução.

Seu `sourcemap` deve aparecer no final do seu código. Ele é definido por uma única linha de comentário que segue o seguinte formato:

```
//# sourceMappingURL=data:application/json;base64,<base64 encoded string>
```

Veja um exemplo abaixo:

```
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsibGliLmpzIiwgImNvZGUuanMiXSwKICAibWFwcGluZ3MiOiAiO0FBQU8sU0FBUyxRQUFRO0FBQ3RCLFNBQU87QUFDVDs7O0FDRE8sU0FBUyxRQUFRLEtBQUs7QUFDM0IsU0FBTyxNQUFNO0FBQ2Y7IiwKICAibmFtZXMiOiBbXQp9Cg==
```

Os mapas de origem podem ser criados com o esbuild. O exemplo abaixo mostra como usar a JavaScript API esbuild para incluir um mapa de origem embutido quando o código é criado e agrupado:

```
/* eslint-disable */
import { build } from 'esbuild'
import eslint from 'esbuild-plugin-eslint'
import glob from 'glob'
const files = await glob('src/**/*.ts')

await build({
  sourcemap: 'inline',
  sourcesContent: false,
  
  format: 'esm',
  target: 'esnext',
  platform: 'node',
  external: ['@aws-appsync/utils'],
  outdir: 'dist/',
  entryPoints: files,
  bundle: true,
  plugins: [eslint({ useEslintrc: true })],
})
```

Em particular, as opções `sourcesContent` e `sourcemap` especificam que um mapa de origem deve ser adicionado in-line no final de cada compilação, mas não deve incluir o conteúdo de origem. Como convenção, recomendamos não incluir o conteúdo de origem em `sourcemap`. É possível desativar isso no esbuild definindo `sources-content` como `false`.

Para ilustrar como os mapas de origem funcionam, revise o exemplo a seguir em que um código de resolvedor faz referência a funções de ajuda de uma biblioteca de ajuda. O código contém instruções de log no código do resolvedor e na biblioteca de ajuda:

**./src/default.resolver.ts** (seu resolvedor)

```
import { Context } from '@aws-appsync/utils'
import { hello, logit } from './helper'

export function request(ctx: Context) {
  console.log('start >')
  logit('hello world', 42, true)
  console.log('< end')
  return 'test'
}

export function response(ctx: Context): boolean {
  hello()
  return ctx.prev.result
}
```

**.src/helper.ts** (um arquivo auxiliar)

```
export const logit = (...rest: any[]) => {
  // a special logger
  console.log('[logger]', ...rest.map((r) => `<${r}>`))
}

export const hello = () => {
  // This just returns a simple sentence, but it could do more.
  console.log('i just say hello..')
}
```

Ao criar e empacotar o arquivo resolvedor, seu código do resolvedor incluirá um mapa de origem in-line. Quando seu resolvedor é executado, as seguintes entradas aparecem nos CloudWatch registros:

![\[CloudWatch log entries showing resolver code execution with inline source map information.\]](http://docs.aws.amazon.com/pt_br/appsync/latest/devguide/images/cloudwatch-sourcemap.jpeg)


Observando as entradas no CloudWatch registro, você notará que a funcionalidade dos dois arquivos foi agrupada e está sendo executada simultaneamente. O nome do arquivo original de cada arquivo também é claramente refletido nos registros.

# Testando seu resolvedor e manipuladores de funções em AWS AppSync
<a name="test-resolvers"></a>

Você pode usar o comando da API `EvaluateCode` para testar remotamente seu resolvedor e manipuladores de funções com dados simulados antes mesmo de salvar seu código em um resolvedor ou função. Para começar a usar o comando, certifique-se de ter adicionado a permissão `appsync:evaluatecode` à sua política. Por exemplo:

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "appsync:evaluateCode",
            "Resource": "arn:aws:appsync:us-east-1:111122223333:*"
        }
    ]
}
```

------

Você pode aproveitar o comando usando a [AWS CLI](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/index.html) ou. [AWS SDKs](https://aws.amazon.com/tools/) Por exemplo, para testar seu código usando a CLI, basta apontar para o arquivo, fornecer um contexto e especificar o manipulador que você deseja avaliar:

```
aws appsync evaluate-code \
  --code file://code.js \
  --function request \
  --context file://context.json \
  --runtime name=APPSYNC_JS,runtimeVersion=1.0.0
```

A resposta tem um `evaluationResult` contendo o payload retornada pelo seu manipulador. Também contém um objeto `logs` com a lista de logs que foram gerados pelo seu manipulador durante a avaliação. Isso facilita a depuração da execução do código e a visualização de informações sobre sua avaliação para ajudar na solução de problemas. Por exemplo:

```
{
    "evaluationResult": "{\"operation\":\"PutItem\",\"key\":{\"id\":{\"S\":\"record-id\"}},\"attributeValues\":{\"owner\":{\"S\":\"John doe\"},\"expectedVersion\":{\"N\":2},\"authorId\":{\"S\":\"Sammy Davis\"}}}",
    "logs": [
        "INFO - code.js:5:3: \"current id\" \"record-id\"",
        "INFO - code.js:9:3: \"request evaluated\""
    ]
}
```

O resultado da avaliação pode ser analisado como JSON, que fornece:

```
{
  "operation": "PutItem",
  "key": {
    "id": {
      "S": "record-id"
    }
  },
  "attributeValues": {
    "owner": {
      "S": "John doe"
    },
    "expectedVersion": {
      "N": 2
    },
    "authorId": {
      "S": "Sammy Davis"
    }
  }
}
```

Usando o SDK, você pode incorporar facilmente testes do seu conjunto de testes para validar o comportamento do código. Este exemplo usa o [Jest Testing Framework](https://jestjs.io/), mas qualquer conjunto de testes funciona. O trecho a seguir mostra uma execução de validação hipotética. Esperamos que a resposta de avaliação seja um JSON válido, por isso, usamos `JSON.parse` para recuperar o JSON da resposta da string:

```
const AWS = require('aws-sdk')
const fs = require('fs')
const client = new AWS.AppSync({ region: 'us-east-2' })
const runtime = {name:'APPSYNC_JS',runtimeVersion:'1.0.0')

test('request correctly calls DynamoDB', async () => {
  const code = fs.readFileSync('./code.js', 'utf8')
  const context = fs.readFileSync('./context.json', 'utf8')
  const contextJSON = JSON.parse(context)
  
  const response = await client.evaluateCode({ code, context, runtime, function: 'request' }).promise()
  const result = JSON.parse(response.evaluationResult)
  
  expect(result.key.id.S).toBeDefined()
  expect(result.attributeValues.firstname.S).toEqual(contextJSON.arguments.firstname)
})
```

Isso produz o seguinte resultado:

```
Ran all test suites.
> jest

PASS ./index.test.js
✓ request correctly calls DynamoDB (543 ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 totalTime: 1.511 s, estimated 2 s
```

# Migrando da VTL para a JavaScript AWS AppSync
<a name="migrating-resolvers"></a>

AWS AppSync permite que você escreva sua lógica de negócios para seus resolvedores e funções usando VTL ou. JavaScript Com as duas linguagens, você escreve uma lógica que instrui o AWS AppSync serviço sobre como interagir com suas fontes de dados. Com o VTL, você grava modelos de mapeamento que devem ser avaliados como uma string válida codificada em JSON. Com JavaScript, você escreve manipuladores de solicitações e respostas que retornam objetos. Você não retorna uma string codificada em JSON.

Por exemplo, use o seguinte modelo de mapeamento de VTL para obter um item do Amazon DynamoDB:

```
{
    "operation": "GetItem",
    "key": {
        "id": $util.dynamodb.toDynamoDBJson($ctx.args.id),
    }
}
```

O utilitário `$util.dynamodb.toDynamoDBJson` retorna uma string codificada em JSON. Se `$ctx.args.id` estiver definido como `<id>`, o modelo será avaliado como uma string válida codificada em JSON:

```
{
    "operation": "GetItem",
    "key": {
        "id": {"S": "<id>"},
    }
}
```

Ao trabalhar com JavaScript, você não precisa imprimir strings brutas codificadas em JSON em seu código, e usar um utilitário como esse não é necessário. `toDynamoDBJson` Um exemplo equivalente do modelo de mapeamento acima é:

```
import { util } from '@aws-appsync/utils';
export function request(ctx) {
  return {
    operation: 'GetItem',
    key: {id: util.dynamodb.toDynamoDB(ctx.args.id)}
  };
}
```

Uma alternativa é usar `util.dynamodb.toMapValues`, que é a abordagem recomendada para manipular um objeto de valores:

```
import { util } from '@aws-appsync/utils';
export function request(ctx) {
  return {
    operation: 'GetItem',
    key: util.dynamodb.toMapValues({ id: ctx.args.id }),
  };
}
```

É avaliado como:

```
{
  "operation": "GetItem",
  "key": {
    "id": {
      "S": "<id>"
    }
  }
}
```

**nota**  
Recomendamos usar o módulo do DynamoDB com as fontes de dados do DynamoDB:  

```
import * as ddb from '@aws-appsync/utils/dynamodb'

export function request(ctx) {
	ddb.get({ key: { id: ctx.args.id } })
}
```

Por exemplo, use o seguinte modelo de mapeamento para obter um item em uma fonte de dados do Amazon DynamoDB:

```
{
    "operation" : "PutItem",
    "key" : {
        "id": $util.dynamodb.toDynamoDBJson($util.autoId()),
    },
    "attributeValues" : $util.dynamodb.toMapValuesJson($ctx.args)
}
```

Quando avaliada, essa string do modelo de mapeamento deve produzir uma string válida codificada em JSON. Ao usar JavaScript, seu código retorna o objeto de solicitação diretamente:

```
import { util } from '@aws-appsync/utils';
export function request(ctx) {
  const { id = util.autoId(), ...values } = ctx.args;
  return {
    operation: 'PutItem',
    key: util.dynamodb.toMapValues({ id }),
    attributeValues: util.dynamodb.toMapValues(values),
  };
}
```

que é avaliado como:

```
{
  "operation": "PutItem",
  "key": {
    "id": { "S": "2bff3f05-ff8c-4ed8-92b4-767e29fc4e63" }
  },
  "attributeValues": {
    "firstname": { "S": "Shaggy" },
    "age": { "N": 4 }
  }
}
```

**nota**  
Recomendamos usar o módulo do DynamoDB com as fontes de dados do DynamoDB:  

```
import { util } from '@aws-appsync/utils'
import * as ddb from '@aws-appsync/utils/dynamodb'

export function request(ctx) {
	const { id = util.autoId(), ...item } = ctx.args
	return ddb.put({ key: { id }, item })
}
```

# Escolha entre acesso direto à fonte de dados e proxy por meio de uma fonte de dados do Lambda
<a name="choosing-data-source"></a>

Com AWS AppSync e o `APPSYNC_JS` tempo de execução, você pode escrever seu próprio código que implemente sua lógica de negócios personalizada usando AWS AppSync funções para acessar suas fontes de dados. Isso facilita a interação direta com fontes de dados como Amazon DynamoDB, Aurora OpenSearch Serverless, Service APIs, HTTP AWS e outros serviços sem precisar implantar serviços computacionais ou infraestrutura adicionais. AWS AppSync também facilita a interação com uma AWS Lambda função configurando uma fonte de dados Lambda. As fontes de dados Lambda permitem que você execute uma lógica comercial complexa usando os recursos completos AWS Lambda do conjunto para resolver uma solicitação do GraphQL. Na maioria dos casos, uma AWS AppSync função conectada diretamente à fonte de dados de destino fornecerá todas as funcionalidades de que você precisa. Em situações em que você precisa implementar uma lógica de negócios complexa que não é suportada pelo runtime `APPSYNC_JS`, você pode usar uma fonte de dados do Lambda como proxy para interagir com sua fonte de dados de destino.


|  |  |  | 
| --- |--- |--- |
|  | Integração direta de fontes de dados | Fonte de dados Lambda como proxy | 
| Caso de uso | AWS AppSync as funções interagem diretamente com as fontes de dados da API. | AWS AppSync funções chamadas de Lambdas que interagem com fontes de dados da API. | 
| Runtime | APPSYNC\$1JS (JavaScript) | Qualquer tempo de execução Lambda compatível | 
| Tamanho máximo do código | 32.000 caracteres por função AWS AppSync | 50 MB (compactado, para upload direto) por Lambda | 
| Módulos externos | Limitado - somente recursos compatíveis com o APPSYNC\$1JS | Sim | 
| Ligue para qualquer AWS serviço | Sim - Usando a fonte de dados AWS AppSync HTTP | Sim - Usando o AWS SDK | 
| Acesso ao cabeçalho da solicitação | Sim | Sim | 
| Acesso à rede | Não | Sim | 
| Acesso ao sistema de arquivos | Não | Sim | 
| Registro e métricas | Sim | Sim | 
| Crie e teste inteiramente dentro AppSync | Sim | Não | 
| Arranque a frio | Não | Não - Com simultaneidade provisionada | 
| Ajuste de escala automático | Sim - de forma transparente por AWS AppSync | Sim - conforme configurado no Lambda | 
| Preços | Sem custo adicional | Cobrado pelo uso do Lambda | 

AWS AppSync funções que se integram diretamente à fonte de dados de destino são ideais para casos de uso como os seguintes:
+  Interagindo com Amazon DynamoDB, Aurora Serverless e Service OpenSearch 
+  Interagindo com HTTP APIs e passando cabeçalhos de entrada 
+  Interagindo com AWS serviços usando fontes de dados HTTP (com solicitações de assinatura AWS AppSync automática com a função de fonte de dados fornecida) 
+  Implementar o controle de acesso antes de acessar as fontes de dados 
+  Implementar a filtragem dos dados recuperados antes de atender a uma solicitação 
+  Implementação de orquestração simples com execução sequencial de AWS AppSync funções em um pipeline de resolução 
+  Controlar conexões de cache e assinatura em consultas e mutações. 

AWS AppSync funções que usam uma fonte de dados Lambda como proxy são ideais para casos de uso como os seguintes:
+  Usando uma linguagem diferente JavaScript da Velocity Template Language (VTL) 
+  Ajustar e controlar a CPU ou a memória para otimizar a performance 
+  Importar bibliotecas de terceiros ou exigir atributos não suportados no `APPSYNC_JS` 
+  Fazer várias solicitações de rede and/or obtendo acesso ao sistema de arquivos para atender a uma consulta 
+  Fazer solicitações em lote usando a [configuração em lote](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-lambda-js.html) 