Agrupación, TypeScript y mapas de origen para el tiempo de ejecución de APPSYNC_JS
TypeScript mejora el desarrollo de AWS AppSync al proporcionar seguridad de tipos y detección temprana de errores. Puede escribir código de TypeScript de forma local y transpilarlo a JavaScript antes de usarlo con el tiempo de ejecución de APPSYNC_JS
. El proceso comienza con la instalación de TypeScript y la configuración de tsconfig.json para el entorno de 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 agrupación combinan el código en un único archivo para usarlo en AWS AppSync. Los mapas de origen se pueden incluir para facilitar la depuración.
Uso de bibliotecas y agrupación del código
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 usar una herramienta de agrupación, como esbuild
Al agrupar el código, tenga en cuenta lo siguiente:
-
APPSYNC_JS
solo admite módulos ECMAScript (ESM). -
Los módulos
@aws-appsync/*
están integrados enAPPSYNC_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.
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
Creación del código y trabajo con TypeScript
TypeScript@aws-appsync/utils
está completamente escrito.
La versión ejecutable APPSYNC_JS
no admite TypeScript directamente. Primero debe transpilar el código de TypeScript a código JavaScript que la versión ejecutable APPSYNC_JS
admita antes de guardar el código en AWS AppSync. Puede usar TypeScript para escribir el código en su entorno de desarrollo integrado (IDE) local, pero tenga en cuenta que no puede crear código de TypeScript en la consola AWS AppSync.
Para empezar, asegúrese de tener TypeScriptAPPSYNC_JS
mediante TSConfigtsconfig.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, en el caso de un proyecto con su código AWS AppSync ubicado en src/appsync
, puede usar el siguiente comando para compilar y agrupar 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
Puede usar la CLI de Amplifyschema.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 }
Podría utilizar los tipos generados en la siguiente función de AWS AppSync 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
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
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 de código que usa la API de JavaScript 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
Puede proporcionar un mapa de origen en línea (sourcemap
) con su código JavaScript. Los mapas de origen son útiles al agrupar código JavaScript o de TypeScript y cuando desea ver referencias a los archivos de origen de entrada en los registros y mensajes de error de JavaScript de la versión ejecutable.
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 API de JavaScript esbuild para incluir un mapa de origen en línea cuando al compilarse y agruparse 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. Al ejecutarse el solucionador, aparecen las siguientes entradas en los registros de CloudWatch:
Si observa las entradas en el registro de CloudWatch, verá que se han agrupado las funcionalidades de los dos archivos y se ejecutan simultáneamente. El nombre original de cada archivo también aparece claramente reflejado en los registros.