

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

# AWS AppSync JavaScript descripción general de los resolutores
<a name="resolver-reference-overview-js"></a>

AWS AppSync le permite responder a las solicitudes de GraphQL realizando operaciones en sus fuentes de datos. Para cada campo de GraphQL en el que desee ejecutar una consulta, mutación o suscripción, se debe asociar un solucionador.

Los solucionadores son los conectores entre GraphQL y un origen de datos. Indican AWS AppSync cómo traducir una solicitud de GraphQL entrante en instrucciones para su fuente de datos de backend y cómo traducir la respuesta de esa fuente de datos de nuevo en una respuesta de GraphQL. Con AWS AppSync él, puedes escribir tus resolutores JavaScript y ejecutarlos en el AWS AppSync entorno (). `APPSYNC_JS` 

AWS AppSync permite escribir resolutores unitarios o resolutores de canalización compuestos por múltiples AWS AppSync funciones en una canalización.

## Características de la versión ejecutable compatibles
<a name="runtime-support-js"></a>

El AWS AppSync JavaScript motor de ejecución proporciona un subconjunto de JavaScript bibliotecas, utilidades y funciones. Para obtener una lista completa de las características y funciones compatibles con el `APPSYNC_JS` motor de ejecución, consulte las [características del JavaScript tiempo de ejecución para resoluciones y funciones](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-util-reference-js.html).

## Solucionadores de unidad
<a name="unit-resolver-js"></a>

Un solucionador de unidad se compone de código que define un controlador de solicitudes y respuestas que se ejecutan con un origen de datos. El controlador de solicitudes toma un objeto de contexto como argumento y devuelve la carga de la solicitud utilizada para llamar al origen de datos. El controlador de respuestas recibe una carga útil del origen de datos con el resultado de la solicitud ejecutada. El controlador de respuestas transforma la carga útil en una respuesta de GraphQL para resolver el campo de GraphQL. En el ejemplo siguiente, un solucionador recupera un elemento de un origen de datos de 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;
```

## Anatomía de un solucionador de JavaScript canalizaciones
<a name="anatomy-of-a-pipeline-resolver-js"></a>

Un solucionador de canalización se compone de un código que define un controlador de solicitudes y respuestas y una lista de funciones. Cada función tiene un controlador de **solicitudes** y **respuestas** que ejecuta con un origen de datos. Puesto que un solucionador de canalización delega las ejecuciones a una lista de funciones, no está vinculado a ningún origen de datos. Las funciones y los solucionadores de unidad son primitivos que ejecutan la operación frente a los orígenes de datos.

### Controlador de solicitudes del solucionador de canalización
<a name="request-handler-js"></a>

El controlador de solicitudes de un solucionador de canalización (el paso Before (Antes)) permite crear alguna lógica de preparación antes de ejecutar las funciones definidas.

### Lista de funciones
<a name="functions-list-js"></a>

La lista de funciones de un solucionador de canalización se ejecutará de forma secuencial. El resultado de la evaluación del controlador de solicitudes del solucionador de canalización estará disponible para la primera función como `ctx.prev.result`. El resultado de la evaluación de cada función está disponible para la siguiente función como `ctx.prev.result`.

### Controlador de respuestas del solucionador de canalización
<a name="response-handler-js"></a>

El controlador de respuestas de un solucionador de canalización permite realizar alguna lógica final a partir del resultado de la última función al tipo de campo GraphQL esperado. El resultado de la última función en lista de funciones está disponible en el controlador de respuestas del solucionador de canalización como `ctx.prev.result` o `ctx.result`.

### Flujo de la ejecución
<a name="execution-flow-js"></a>

Con un solucionador de canalización compuesto por dos funciones, la lista siguiente representa el flujo de ejecución cuando se invoca el solucionador:

1.  Controlador de solicitudes del solucionador de canalización

1.  Función 1: Controlador de solicitudes de función 

1.  Función 1: Invocación de origen de datos 

1.  Función 1: Controlador de respuestas de función 

1.  Función 2: Controlador de solicitudes de función 

1.  Función 2: Invocación de origen de datos 

1.  Función 2: Controlador de respuestas de función 

1.  Controlador de respuestas del solucionador de canalización 

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


### Utilidades integradas de tiempo de ejecución `APPSYNC_JS` prácticas
<a name="useful-utilities-js"></a>

Las siguientes utilidades pueden ayudar cuando se trabaja con solucionadores de canalización.

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

El stash es un objeto que está disponible dentro de cada solucionador y controlador de solicitudes y respuestas de función. La misma instancia stash vive en una única ejecución de solucionador. Esto significa que puede utilizar el stash para pasar datos arbitrarios a controladores de solicitudes y respuestas, así como a las funciones de un solucionador de canalización. Puedes probar el alijo como si fuera un JavaScript objeto normal.

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

El `ctx.prev.result` representa el resultado de la operación anterior que se ha ejecutado en la canalización. Si la operación anterior era el controlador de solicitudes del solucionador de canalización, entonces `ctx.prev.result` estará disponible para la primera función de la cadena. Si la operación anterior era la primera función, entonces `ctx.prev.result` representa el resultado de la primera función y estará disponible para la segunda función de la canalización. Si la operación anterior era la última función, entonces `ctx.prev.result` representa el resultado de la última función y estará disponible para el controlador de respuestas del solucionador de canalización.

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

La utilidad `util.error` es útil para lanzar un error de campo. El uso de `util.error` dentro de un controlador de solicitudes o respuestas de función genera un error de campo inmediatamente, lo que impide que se ejecuten funciones posteriores. Para obtener más información y otras `util.error` firmas, visita las [características del JavaScript tiempo de ejecución para ver resoluciones y funciones](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-util-reference-js.html).

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

El `util.appendError` es similar a `util.error()`, siendo la principal diferencia que no interrumpe la evaluación del controlador. En su lugar, indica que hubo un error con el campo, pero permite evaluar el controlador y, por tanto, devolver los datos. El uso de `util.appendError` dentro de una función no interrumpe el flujo de ejecución de la canalización. Para obtener más información y otras `util.error` firmas, visita las [características del JavaScript tiempo de ejecución para ver los resolutores y las](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-util-reference-js.html) funciones.

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

La función `runtime.earlyReturn` permite volver de forma prematura de cualquier función de solicitud. Al utilizar `runtime.earlyReturn` dentro de un controlador de solicitudes del solucionador volverá desde el solucionador. Si se llama desde un controlador de solicitudes de función de AWS AppSync volverá desde la función y continuará la ejecución a la siguiente función del controlador de respuestas del solucionador o canalización.

### Escritura de solucionadores de canalización
<a name="writing-resolvers"></a>

Un solucionador de canalización también tiene un controlador de solicitudes y otro de respuestas relacionados con la ejecución de las funciones en la canalización: su controlador de solicitudes se ejecuta antes de la solicitud de la primera función y su controlador de respuestas lo hace después de la respuesta de la última función. El controlador de solicitudes del solucionador puede configurar los datos para que las funciones de la canalización los utilicen. El controlador de respuestas del solucionador es responsable de devolver los datos que se mapean al tipo de salida del campo GraphQL. En el siguiente ejemplo, un controlador de solicitudes del solucionador define `allowedGroups`; los datos devueltos deben pertenecer a uno de estos grupos. Las funciones del solucionador pueden utilizar este valor para solicitar datos. El controlador de respuestas del solucionador realiza una comprobación final y filtra el resultado para asegurarse de que solo se devuelvan los elementos pertenecientes a los grupos permitidos.

```
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;
}
```

#### Funciones de escritura AWS AppSync
<a name="writing-functions"></a>

AWS AppSync las funciones le permiten escribir una lógica común que puede reutilizar en varios solucionadores de su esquema. Por ejemplo, puede tener una AWS AppSync función llamada `QUERY_ITEMS` que se encargue de consultar los elementos de una fuente de datos de Amazon DynamoDB. En el caso de los solucionadores con los que desea consultar elementos, solo tiene que añadir la función a la canalización del solucionador y proporcionar el índice de consulta que se va a usar. No es necesario volver a implementar la lógica.

## Temas complementarios
<a name="supplemental-topics"></a>

**Temas**
+ [Ejemplo de solucionador de canalización con Amazon DynamoDB](https://docs.aws.amazon.com/appsync/latest/devguide/writing-code.html)
+ [Configuración de utilidades para el tiempo de ejecución de `APPSYNC_JS`](https://docs.aws.amazon.com/appsync/latest/devguide/utility-resolvers.html)
+ [Mapas agrupados y fuente para TypeScript el tiempo de ejecución `APPSYNC_JS`](https://docs.aws.amazon.com/appsync/latest/devguide/additional-utilities.html)
+ [Prueba del solucionador y de los controladores de funciones](https://docs.aws.amazon.com/appsync/latest/devguide/test-resolvers.html)
+ [Migración de VTL a JavaScript](https://docs.aws.amazon.com/appsync/latest/devguide/migrating-resolvers.html)
+ [Elección entre acceso directo a los orígenes de datos y proxies a través de un origen de datos de Lambda](https://docs.aws.amazon.com/appsync/latest/devguide/choosing-data-source.html)

# Ejemplo de solucionador de canalización con Amazon DynamoDB
<a name="writing-code"></a>

Supongamos que desea asociar un solucionador de canalización a un campo llamado `getPost(id:ID!)` que devuelve un tipo `Post` de un origen de datos de Amazon DynamoDB con la consulta de GraphQL siguiente:

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

En primer lugar, adjunte un solucionador sencillo a `Query.getPost` con el siguiente código. Este es un ejemplo de código de solucionador sencillo. No hay ninguna lógica definida en el controlador de solicitudes, y el controlador de respuestas simplemente devuelve el resultado de la última función.

```
/**
 * 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
}
```

A continuación, defina la función `GET_ITEM` que recupera un elemento postitem del origen de datos:

```
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
}
```

Si se produce un error durante la solicitud, el controlador de respuestas de la función agrega un error que se devolverá al cliente que realiza la llamada en la respuesta de GraphQL. Añada la función `GET_ITEM` a su lista de funciones de solucionador. Al ejecutar la consulta, el controlador de solicitudes de la `GET_ITEM` función utiliza las utilidades proporcionadas por el módulo AWS AppSync DynamoDB para crear una `DynamoDBGetItem` solicitud con la como clave. `id` `ddb.get({ key: { id } })`genera la operación adecuada: `GetItem`

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

AWS AppSync utiliza la solicitud para obtener los datos de Amazon DynamoDB. Una vez devueltos los datos, los administra el controlador de respuestas de la función `GET_ITEM`, que comprueba si hay errores y, a continuación, devuelve el resultado. 

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

Por último, el controlador de respuestas del solucionador devuelve el resultado directamente.

## Solución de errores
<a name="working-with-errors"></a>

Si se produce un error en su función durante una solicitud, el error estará disponible en el controlador de respuestas de función en `ctx.error`. Puede agregar el error a su respuesta de GraphQL mediante la utilidad `util.appendError`. Puede hacer que el error esté disponible para otras funciones en la canalización con el stash. Vea el ejemplo siguiente:

```
/**
 * 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;
}
```

# Configuración de utilidades para el tiempo de ejecución de `APPSYNC_JS`
<a name="utility-resolvers"></a>

AWS AppSync proporciona dos bibliotecas que ayudan al desarrollo de resolutores con el tiempo de ejecución: `APPSYNC_JS` 
+ `@aws-appsync/eslint-plugin`: identifica y soluciona problemas rápidamente durante el desarrollo.
+ `@aws-appsync/utils`: proporciona la validación de tipos y la función de autocompletar en editores de código.

## Configuración del complemento de eslint
<a name="utility-resolvers-configuring-eslint-plugin"></a>

[ESLint](https://eslint.org/)es una herramienta que analiza estáticamente el código para encontrar problemas rápidamente. Puede ejecutarlo ESLint como parte de su proceso de integración continua. `@aws-appsync/eslint-plugin`es un ESLint complemento que detecta la sintaxis no válida de tu código al aprovechar el `APPSYNC_JS` tiempo de ejecución. El complemento permite recibir comentarios sobre el código de forma rápida durante el desarrollo sin tener que enviar los cambios a la nube.

`@aws-appsync/eslint-plugin` proporciona dos conjuntos de reglas que puede usar durante el desarrollo. 

**"plugin:@aws-appsync/base"** configura un conjunto básico de reglas que puede aprovechar en su proyecto: 


| Regla | Description (Descripción) | 
| --- | --- | 
| no-async | No se admiten promesas ni procesos asíncronos. | 
| no-await | No se admiten promesas ni procesos asíncronos. | 
| no-classes | No se admiten clases. | 
| no-for | No se admite for (excepto para for-in y for-of, que sí se admiten) | 
| no-continue | No se admite continue. | 
| no-generators | No se admiten generadores. | 
| no-yield | yield no se admite. | 
| no-labels | No se admiten etiquetas. | 
| no-this | No se admite la palabra clave this. | 
| no-try | No se admite la estructura try/catch. | 
| no-while | No se admiten los bucles WHILE. | 
| no-disallowed-unary-operators | No se permiten los operadores unarios \$1\$1, -- y \$1. | 
| no-disallowed-binary-operators | No se permite el operador instanceof. | 
| no-promise | No se admiten promesas ni procesos asíncronos. | 

**«plugin: @aws -appsync/recommended»** proporciona algunas reglas adicionales, pero también requiere que TypeScript añadas configuraciones a tu proyecto.


| Regla | Description (Descripción) | 
| --- | --- | 
| no-recursion | No se permiten llamadas a funciones recursivas. | 
| no-disallowed-methods | No se permiten algunos métodos. Consulte la [referencia](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-util-reference-js.html) para obtener un conjunto completo de funciones integradas compatibles. | 
| no-function-passing | No se permite pasar funciones como argumentos de la función a funciones. | 
| no-function-reassign | No se pueden reasignar funciones. | 
| no-function-return | Las funciones no pueden ser el valor devuelto de las funciones. | 

[Para añadir el complemento a tu proyecto, sigue los pasos de instalación y uso que se indican en Primeros pasos. ESLint](https://eslint.org/docs/latest/user-guide/getting-started#installation-and-usage) A continuación, instale el [complemento](https://www.npmjs.com/package/@aws-appsync/eslint-plugin) en su proyecto con el administrador de paquetes del proyecto (por ejemplo, npm, yarn o pnpm):

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

En el archivo `.eslintrc.{js,yml,json}`, añada **"plugin:@aws-appsync/base"** o **"plugin:@aws-appsync/recommended"** a la propiedad `extends`. El siguiente fragmento es un ejemplo de `.eslintrc` configuración básica para: JavaScript 

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

Para usar el conjunto de reglas **"plugin:@aws-appsync/recommended"**, instale la dependencia requerida:

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

A continuación, cree un archivo `.eslintrc.js`:

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

# Mapas agrupados y fuente para el tiempo de ejecución TypeScript `APPSYNC_JS`
<a name="additional-utilities"></a>

TypeScript mejora AWS AppSync el desarrollo al proporcionar seguridad tipográfica y detección temprana de errores. Puede escribir TypeScript código localmente y transpilarlo JavaScript antes de usarlo con el `APPSYNC_JS` motor de ejecución. El proceso comienza con la instalación TypeScript y configuración de tsconfig.json para el entorno. `APPSYNC_JS` A continuación, puede usar herramientas de agrupación como esbuild para compilar y agrupar el código. La CLI de Amplify generará tipos a partir del esquema de GraphQL, lo que permite usar dichos tipos en el código del solucionador. 

Puede usar bibliotecas personalizadas y externas en el código de solucionador y función, siempre que cumplan los requisitos de `APPSYNC_JS`. Las herramientas de agrupamiento combinan el código en un solo archivo para su uso en él. AWS AppSync Los mapas de origen se pueden incluir para facilitar la depuración. 

## Uso de bibliotecas y agrupación del código
<a name="using-external-libraries"></a>

En su código de solucionador y función, puede utilizar bibliotecas personalizadas y externas siempre que cumplan los requisitos de `APPSYNC_JS`. Esto permite reutilizar el código existente en su aplicación. Para utilizar bibliotecas definidas por varios archivos, debe utilizar una herramienta de agrupamiento, como [esbuild](https://esbuild.github.io/), para combinar el código en un único archivo que, a continuación, se pueda guardar en su AWS AppSync resolución o función.

Al agrupar el código, tenga en cuenta lo siguiente:
+ `APPSYNC_JS`solo admite ECMAScript módulos (ESM).
+ Los módulos `@aws-appsync/*` están integrados en `APPSYNC_JS` y no deben agruparse con su código.
+ El entorno de versión ejecutable `APPSYNC_JS` es similar a NodeJS en que el código no se ejecuta en un entorno del navegador.
+ Puede incluir un mapa de origen opcional. Sin embargo, no incluya el contenido de origen.

  Para obtener más información sobre los mapas de origen, consulte [Uso de mapas de origen](#source-maps).

Por ejemplo, para agrupar el código de solucionador ubicado en `src/appsync/getPost.resolver.js`, puede usar el siguiente comando de la 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
```

## Construye tu código y trabaja con TypeScript
<a name="working-with-typescript"></a>

[TypeScript](https://www.typescriptlang.org/)es un lenguaje de programación desarrollado por Microsoft que ofrece todas las JavaScript funciones junto con el sistema de TypeScript mecanografía. Puedes usarlo TypeScript para escribir código de tipo seguro y detectar errores y errores en el momento de la compilación antes de guardar tu código en. AWS AppSync El paquete `@aws-appsync/utils` está completamente escrito.

El `APPSYNC_JS` tiempo de ejecución no es compatible TypeScript directamente. Primero debe transpilar el TypeScript código a JavaScript un código compatible con el `APPSYNC_JS` motor de ejecución antes de guardar el código en él. AWS AppSync Puede usarlo TypeScript para escribir el código en su entorno de desarrollo integrado (IDE) local, pero tenga en cuenta que no puede crear TypeScript código en la AWS AppSync consola.

Para empezar, asegúrate de haberlo [TypeScript](https://www.typescriptlang.org/download)instalado en tu proyecto. A continuación, configure los ajustes de TypeScript transcompilación para que funcionen con el `APPSYNC_JS` motor de ejecución que utiliza [TSConfig](https://www.typescriptlang.org/tsconfig). Este es un ejemplo de un archivo `tsconfig.json` básico que puede usar:

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

A continuación, puede usar una herramienta de agrupación como esbuild para compilar y agrupar el código. Por ejemplo, si se trata de un proyecto con el AWS AppSync código ubicado en`src/appsync`, puede usar el siguiente comando para compilar y empaquetar el 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
```

### Uso de CodeGen de Amplify
<a name="working-with-amplify-codegen"></a>

Puede usar la [CLI de Amplify](https://docs.amplify.aws/cli/) a fin de generar los tipos para su esquema. En el directorio donde se encuentra su archivo `schema.graphql`, ejecute el siguiente comando y revise las instrucciones para configurar el CodeGen:

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

Para regenerar el CodeGen en determinadas circunstancias (por ejemplo, cuando se actualiza el esquema), ejecute el siguiente comando:

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

A continuación, puede usar los tipos generados en el código de solucionador. Por ejemplo, en el caso del esquema siguiente:

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

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

type Query {
  listTodos: Todo
}
```

Puedes usar los tipos generados en la siguiente AWS AppSync función de ejemplo:

```
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
}
```

### Uso de genéricos en TypeScript
<a name="working-with-typescript-generics"></a>

Puede usar genéricos con varios de los tipos proporcionados. Por ejemplo, el siguiente fragmento de código es un tipo `Todo`:

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

Puede escribir un solucionador para una suscripción que haga uso de `Todo`. En su IDE, las definiciones de tipo y las sugerencias de autocompletar servirán como guía para utilizar correctamente la utilidad de transformación `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
}
```

## Análisis de sus paquetes
<a name="using-lint-with-bundles"></a>

Puede analizar sus paquetes automáticamente mediante la importación del complemento `esbuild-plugin-eslint`. Después, puede habilitarlo proporcionando un valor `plugins` que habilite las capacidades de eslint. A continuación se muestra un fragmento que usa la JavaScript API esbuild en un archivo llamado: `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 })],
})
```

## Uso de mapas de origen
<a name="source-maps"></a>

Puede proporcionar un mapa fuente en línea (`sourcemap`) con su código. JavaScript Los mapas fuente son útiles cuando empaquetas JavaScript o TypeScript codificas y quieres ver las referencias a los archivos fuente de entrada en los registros y los mensajes de JavaScript error del tiempo de ejecución.

Su `sourcemap` debe aparecer al final del código. Se define mediante una única línea de comentario que sigue el siguiente formato:

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

A continuación se muestra un ejemplo:

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

Los mapas de origen se pueden crear con esbuild. En el siguiente ejemplo, se muestra cómo usar la JavaScript API esbuild para incluir un mapa fuente en línea al compilar y empaquetar el código:

```
/* 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 })],
})
```

En concreto, las opciones `sourcemap` y `sourcesContent` especifican que se debe añadir un mapa de origen en línea al final de cada compilación, pero no debe incluir el contenido de origen. Por convención, se recomienda no incluir el contenido de origen en el `sourcemap`. Establezca `sources-content` en `false` para deshabilitarlo en esbuild.

Para ilustrar el funcionamiento de los mapas de origen, revise el siguiente ejemplo, en el que un código de solucionador hace referencia a funciones auxiliares de una biblioteca auxiliar. El código contiene instrucciones de registro en el código de solucionador y en la biblioteca auxiliar:

**./src/default.resolver.ts** (su solucionador)

```
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** (un archivo 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..')
}
```

Al compilar y agrupar el archivo de resolución, el código de solucionador incluirá un mapa de origen en línea. Cuando se ejecuta el solucionador, aparecen las siguientes entradas en los registros: CloudWatch 

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


Al observar las entradas del CloudWatch registro, observará que las funciones de los dos archivos se han agrupado y se ejecutan simultáneamente. El nombre original de cada archivo también aparece claramente reflejado en los registros.

# Probando el resolutor y los controladores de funciones en AWS AppSync
<a name="test-resolvers"></a>

Puede usar el comando de la API de `EvaluateCode` para probar de forma remota su solucionador y sus controladores de función con datos simulados antes de guardar el código en un solucionador o una función. Para comenzar a utilizar el comando, asegúrese de haber añadido el permiso `appsync:evaluatecode` a su política. Por ejemplo:

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

****  

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

------

Puede aprovechar el comando mediante la [AWS CLI](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/index.html) o [AWS SDKs](https://aws.amazon.com/tools/). Por ejemplo, para probar el código con la CLI, basta con apuntar al archivo, proporcionar un contexto y especificar el controlador que desea evaluar:

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

La respuesta contiene un `evaluationResult` que incluye la carga útil devuelta por el controlador. También contiene un objeto `logs` que incluye la lista de registros generados por el controlador durante la evaluación. Esto facilita la depuración de la ejecución de código y la consulta de información sobre la evaluación como ayuda para solucionar problemas. Por ejemplo:

```
{
    "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\""
    ]
}
```

El resultado de la evaluación se puede analizar como JSON, lo que da como resultado:

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

Cuando se utiliza el SDK, puede incorporar fácilmente pruebas de su conjunto de pruebas para validar el comportamiento del código. En nuestro ejemplo aquí mostrado, se utiliza el [marco de pruebas de Jest](https://jestjs.io/), pero cualquier conjunto de pruebas funciona. En el siguiente fragmento de código se muestra una ejecución de validación hipotética. Tenga en cuenta que esperamos que la respuesta de la evaluación sea un JSON válido, por lo que utilizamos `JSON.parse` para recuperar el JSON de la respuesta de cadena:

```
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)
})
```

Esto produce el siguiente 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
```

# Migración de VTL a in JavaScript AWS AppSync
<a name="migrating-resolvers"></a>

AWS AppSync le permite escribir la lógica empresarial para sus resolutores y funciones mediante VTL o. JavaScript En ambos lenguajes, se escribe una lógica que indica al AWS AppSync servicio cómo interactuar con las fuentes de datos. Con VTL, escribe plantillas de mapeo que deben evaluarse como una cadena codificada en JSON válida. Con él JavaScript, escribes controladores de solicitudes y respuestas que devuelven objetos. No devuelve una cadena codificada en JSON.

Por ejemplo, tome la siguiente plantilla de mapeo VTL para obtener un elemento de Amazon DynamoDB:

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

La utilidad `$util.dynamodb.toDynamoDBJson` devuelve una cadena codificada en JSON. Si `$ctx.args.id` se establece en `<id>`, la plantilla se evalúa como una cadena codificada en JSON válida:

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

Al trabajar con ellos JavaScript, no es necesario imprimir cadenas codificadas en JSON sin procesar en el código, y tampoco `toDynamoDBJson` es necesario utilizar una utilidad similar. Un ejemplo equivalente de la plantilla de mapeo anterior es:

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

Una alternativa es utilizar `util.dynamodb.toMapValues`, que es el enfoque recomendado para gestionar un objeto de valores:

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

Esto se evalúa como:

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

**nota**  
Recomendamos utilizar el módulo de DynamoDB con orígenes de datos de DynamoDB:  

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

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

Como otro ejemplo, tome la siguiente plantilla de mapeo para colocar un elemento en un origen de datos de Amazon DynamoDB:

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

Durante su evaluación, esta cadena de plantilla de mapeo debe producir una cadena codificada en JSON válida. Cuando lo usas JavaScript, tu código devuelve el objeto de solicitud directamente:

```
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 se evalúa como:

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

**nota**  
Recomendamos utilizar el módulo de DynamoDB con orígenes de datos de 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 })
}
```

# Elección entre acceso directo a los orígenes de datos y proxies a través de un origen de datos de Lambda
<a name="choosing-data-source"></a>

Con AWS AppSync el `APPSYNC_JS` motor de ejecución, puede escribir su propio código que implemente su lógica empresarial personalizada mediante el uso de AWS AppSync funciones para acceder a sus fuentes de datos. Esto le facilita la interacción directa con fuentes de datos como Amazon DynamoDB, Aurora OpenSearch Serverless, Service APIs, HTTP AWS y otros servicios sin tener que implementar infraestructura o servicios computacionales adicionales. AWS AppSync también facilita la interacción con una AWS Lambda función mediante la configuración de una fuente de datos Lambda. Las fuentes de datos Lambda le permiten ejecutar una lógica empresarial compleja utilizando todas las capacidades AWS Lambda del conjunto para resolver una solicitud de GraphQL. En la mayoría de los casos, una AWS AppSync función conectada directamente a su fuente de datos de destino proporcionará todas las funciones que necesita. En situaciones en las que necesita implementar una lógica empresarial compleja incompatible con la versión ejecutable `APPSYNC_JS`, puede utilizar un origen de datos de Lambda como proxy para interactuar con el origen de datos de destino.


|  |  |  | 
| --- |--- |--- |
|  | Integración directa de la fuente de datos | Fuente de datos Lambda como proxy | 
| Caso de uso | AWS AppSync las funciones interactúan directamente con las fuentes de datos de la API. | AWS AppSync funciones llamadas Lambdas que interactúan con las fuentes de datos de la API. | 
| Tiempo de ejecución | APPSYNC\$1JS (JavaScript) | Cualquier entorno de ejecución de Lambda compatible | 
| Tamaño máximo del código | 32.000 caracteres por función AWS AppSync | 50 MB (comprimidos, para carga directa) por Lambda | 
| Módulos externos | Limitado: solo funciones compatibles con APPSYNC\$1JS | Sí | 
| Llama a cualquier servicio AWS  | Sí, utilizando una fuente de datos AWS AppSync HTTP | Sí, utilizando el SDK AWS  | 
| Acceso al encabezado de la solicitud | Sí | Sí | 
| Acceso a la red | No | Sí | 
| Acceso al sistema de archivos | No | Sí | 
| Registro y métricas | Sí | Sí | 
| Cree y pruebe completamente desde dentro AppSync | Sí | No | 
| Arranque en frío | No | No, con simultaneidad aprovisionada | 
| Escalado automático | Sí, de forma transparente mediante AWS AppSync | Sí, tal como está configurado en Lambda | 
| Precios | Sin cargo adicional | Se cobra por el uso de Lambda | 

AWS AppSync las funciones que se integran directamente con la fuente de datos de destino son ideales para casos de uso como los siguientes:
+  Interacción con Amazon DynamoDB, Aurora Serverless y Service OpenSearch 
+  Interactuar con HTTP APIs y pasar los encabezados entrantes 
+  Interactuar con AWS los servicios mediante fuentes de datos HTTP (firmando AWS AppSync automáticamente las solicitudes con la función de fuente de datos proporcionada) 
+  Implementación del control de acceso antes de acceder a orígenes de datos 
+  Implementación del filtrado de datos recuperados antes de cumplir una solicitud 
+  Implementación de una orquestación sencilla con ejecución secuencial de AWS AppSync funciones en una canalización de resolución 
+  Control de conexiones de suscripción y almacenamiento en caché en consultas y mutaciones. 

AWS AppSync las funciones que utilizan una fuente de datos Lambda como proxy son ideales para casos de uso como los siguientes:
+  Utilizar un lenguaje distinto JavaScript del lenguaje de plantillas Velocity (VTL) 
+  Ajuste y control de la CPU o memoria para optimizar el rendimiento 
+  Importación de bibliotecas de terceros o solicitud de características no compatibles en `APPSYNC_JS` 
+  Realizar múltiples solicitudes de red and/or para obtener acceso al sistema de archivos para responder a una consulta 
+  Procesamiento por lotes de solicitudes mediante la [ configuración de procesamiento por lotes](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-lambda-js.html). 