

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.

# Uso de operaciones de Delta Sync en fuentes de datos versionadas en AWS AppSync
<a name="tutorial-delta-sync"></a>

**nota**  
Ahora admitimos de forma básica el tiempo de ejecución APPSYNC\$1JS y su documentación. Considere la opción de utilizar el tiempo de ejecución APPSYNC\$1JS y sus guías [aquí](https://docs.aws.amazon.com/appsync/latest/devguide/tutorials-js.html).

Las aplicaciones cliente AWS AppSync almacenan datos almacenando en caché las respuestas de GraphQL localmente en mobile/web el disco de una aplicación. Los orígenes de datos con control de versiones y las operaciones `Sync` ofrecen a los clientes la posibilidad de realizar el proceso de sincronización mediante un único solucionador. Esto permite a los clientes incorporar a su memoria caché local los resultados de una consulta de base que podría tener una gran cantidad de registros y, a continuación, recibir solo los datos alterados desde la última consulta (las *actualizaciones delta*). Al permitir que los clientes realicen la incorporación de la caché con una consulta inicial y las actualizaciones incrementales con otra, puede mover el cálculo desde la aplicación cliente al backend. Esto es sustancialmente más eficiente para las aplicaciones cliente que cambian con frecuencia entre estados en línea y sin conexión.

Para implementar Delta Sync, la consulta `Sync` utiliza la operación `Sync` en un origen de datos con control de versiones. Cuando una AWS AppSync mutación cambia un elemento de una fuente de datos versionada, también se almacenará un registro de ese cambio en la tabla *Delta*. Puede optar por utilizar diferentes tablas *Delta* (por ejemplo, una por tipo, una por área de dominio) para otras fuentes de datos versionadas o una sola tabla *Delta* para su API. AWS AppSync recomienda no utilizar una sola tabla *Delta* para varias, APIs a fin de evitar la colisión de las claves principales.

Además, los clientes Delta Sync también pueden recibir una suscripción como argumento y, a continuación, la suscripción de coordenadas del cliente vuelve a conectar y escribe entre transiciones de sin conexión y online. Delta Sync realiza esto reanudando automáticamente las suscripciones (incluido el retardo exponencial y el reintento con fluctuación a través de diferentes escenarios de error de red) y almacenando los eventos en una cola. Entonces la consulta delta o base adecuada se ejecuta antes de fusionar cualquier evento de la cola y, por último, procesar las suscripciones como normales.

La documentación sobre las opciones de configuración del cliente, incluida Amplify DataStore, está disponible en el sitio web de [Amplify](https://aws-amplify.github.io/) Framework. En esta documentación se describe cómo configurar las operaciones `Sync` y los orígenes de datos de DynamoDB con control de versiones para que funcionen con el cliente de Delta Sync y obtener un acceso óptimo a los datos.

## Configuración en un clic
<a name="one-click-setup"></a>

Para configurar automáticamente el punto final de GraphQL AWS AppSync con todos los resolutores configurados y los AWS recursos necesarios, usa esta plantilla: AWS CloudFormation 

[https://console.aws.amazon.com/cloudformation/home?region=us-west-2#/stacks/new?templateURL=https://s3.us-west-2.amazonaws.com/awsappsync/resources/deltasync/deltasync-v2-full.yaml](https://console.aws.amazon.com/cloudformation/home?region=us-west-2#/stacks/new?templateURL=https://s3.us-west-2.amazonaws.com/awsappsync/resources/deltasync/deltasync-v2-full.yaml) 

Esta pila crea los siguientes recursos en su cuenta:
+ 2 tablas de DynamoDB (Base y Delta)
+ 1 AWS AppSync API con clave de API
+ 1 rol de IAM con política para tablas de DynamoDB

Se utilizan dos tablas para particionar las consultas de Sync en una segunda tabla que actúa como un diario de los eventos no atendidos cuando los clientes estaban sin conexión. Para mantener la eficacia de las consultas en la tabla delta, se utiliza [Amazon TTLs DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/TTL.html) para organizar automáticamente los eventos según sea necesario. El tiempo TTL se puede configurar según sus necesidades en el origen de datos (puede configurarlo en 1 hora, 1 día, etc.).

## Esquema
<a name="schema"></a>

Para demostrar Delta Sync, la aplicación de ejemplo crea un esquema de *Posts* respaldado por una tabla *Base* y *Delta* en DynamoDB. AWS AppSync escribe automáticamente las mutaciones en ambas tablas. La consulta Sync extrae registros de la tabla *Base* o *Delta* según proceda y se define una sola suscripción para mostrar cómo los clientes pueden aprovechar esto en su lógica de reconexión.

```
input CreatePostInput {
    author: String!
    title: String!
    content: String!
    url: String
    ups: Int
    downs: Int
    _version: Int
}

interface Connection {
  nextToken: String
  startedAt: AWSTimestamp!
}

type Mutation {
    createPost(input: CreatePostInput!): Post
    updatePost(input: UpdatePostInput!): Post
    deletePost(input: DeletePostInput!): Post
}

type Post {
    id: ID!
    author: String!
    title: String!
    content: String!
    url: AWSURL
    ups: Int
    downs: Int
    _version: Int
    _deleted: Boolean
    _lastChangedAt: AWSTimestamp!
}

type PostConnection implements Connection {
    items: [Post!]!
    nextToken: String
    startedAt: AWSTimestamp!
}

type Query {
    getPost(id: ID!): Post
    syncPosts(limit: Int, nextToken: String, lastSync: AWSTimestamp): PostConnection!
}

type Subscription {
    onCreatePost: Post
        @aws_subscribe(mutations: ["createPost"])
    onUpdatePost: Post
        @aws_subscribe(mutations: ["updatePost"])
    onDeletePost: Post
        @aws_subscribe(mutations: ["deletePost"])
}

input DeletePostInput {
    id: ID!
    _version: Int!
}

input UpdatePostInput {
    id: ID!
    author: String
    title: String
    content: String
    url: String
    ups: Int
    downs: Int
    _version: Int!
}

schema {
    query: Query
    mutation: Mutation
    subscription: Subscription
}
```

El esquema GraphQL es estándar, pero vale la pena señalar un par de cosas antes de avanzar. Primero, todas las mutaciones se escriben automáticamente en la tabla *Base* y, luego, en la tabla *Delta*. La tabla de *Base* es el origen central de información de estado mientras que la tabla *Delta* es el diario. Si no se pasa el `lastSync: AWSTimestamp`, la consulta `syncPosts` se ejecuta con respecto a la tabla *Base* e hidrata la caché, además de ejecutarse de forma periódica como un *proceso de alcance global* para casos límite en los que los clientes están sin conexión más del tiempo TTL configurado en la tabla *Delta*. Si pasa el `lastSync: AWSTimestamp`, la consulta `syncPosts` se ejecuta con respecto a la tabla *Delta* y los clientes la utilizan para recuperar los eventos cambiados desde la última vez que estuvieron sin conexión. Los clientes de Amplify pasan automáticamente el valor `lastSync: AWSTimestamp` y lo conservan en disco debidamente.

El campo *\$1deleted* de *Post* se utiliza para las operaciones **DELETE**. Cuando los clientes están sin conexión y se eliminan registros de la tabla *Base*, este atributo notifica a los clientes que están realizando la sincronización que expulsen los elementos de su caché local. En los casos en que los clientes están offline durante períodos más largos y el elemento se ha eliminado antes de que el cliente pueda recuperar este valor con una consulta Delta Sync, el evento de alcance global de consulta base (configurable en el cliente) se ejecuta y elimina el elemento de la caché. Este campo se marca como opcional porque solo devuelve un valor al ejecutar una consulta Sync que ha eliminado los elementos presentes.

## Mutaciones
<a name="mutations"></a>

Para todas las mutaciones, AWS AppSync realiza una Create/Update/Delete operación estándar en la tabla *base* y también registra el cambio en la tabla *Delta* automáticamente. Puede reducir o ampliar el tiempo para conservar los registros modificando el valor `DeltaSyncTableTTL` en el origen de datos. Para las organizaciones con una alta velocidad de datos, se recomienda que sea breve. O bien, si sus clientes están sin conexión durante períodos más largos, puede ser prudente mantenerlo más tiempo.

## Consultas Sync
<a name="sync-queries"></a>

La *consulta base* es una operación de DynamoDB Sync sin un valor de `lastSync` especificado. Para muchas organizaciones, esto funciona porque la consulta de base solo se ejecuta durante el inicio y de forma periódica a partir de entonces.

La *consulta delta* es una operación de DynamoDB Sync con un valor de `lastSync` especificado. La *consulta delta* se ejecuta cada vez que el cliente vuelva a estar online de un estado sin conexión (siempre que el tiempo periódico de consulta de base no se haya activado para ejecutarse). Los clientes realizan automáticamente el seguimiento de la última vez que ejecutaron de forma correcta una consulta para sincronizar datos.

Cuando se ejecuta una consulta delta, el solucionador de la consulta utiliza `ds_pk` y `ds_sk` para consultar únicamente los registros que han cambiado desde la última vez que el cliente realizó una sincronización. El cliente almacena la respuesta GraphQL adecuada.

Para obtener más información sobre cómo ejecutar consultas Sync, consulte la [documentación de la operación de sincronización](aws-appsync-conflict-detection-and-sync-sync-operations.md).

## Ejemplo
<a name="example"></a>

Vamos a comenzar por llamar a una mutación `createPost` para crear un elemento:

```
mutation create {
  createPost(input: {author: "Nadia", title: "My First Post", content: "Hello World"}) {
    id
    author
    title
    content
    _version
    _lastChangedAt
    _deleted
  }
}
```

El valor de retorno de esta mutación tendrá el siguiente aspecto:

```
{
  "data": {
    "createPost": {
      "id": "81d36bbb-1579-4efe-92b8-2e3f679f628b",
      "author": "Nadia",
      "title": "My First Post",
      "content": "Hello World",
      "_version": 1,
      "_lastChangedAt": 1574469356331,
      "_deleted": null
    }
  }
}
```

Si examina el contenido de la tabla *Base*, verá un registro similar a este:

```
{
  "_lastChangedAt": {
    "N": "1574469356331"
  },
  "_version": {
    "N": "1"
  },
  "author": {
    "S": "Nadia"
  },
  "content": {
    "S": "Hello World"
  },
  "id": {
    "S": "81d36bbb-1579-4efe-92b8-2e3f679f628b"
  },
  "title": {
    "S": "My First Post"
  }
}
```

Si examina el contenido de la tabla *Delta*, verá un registro que tiene el siguiente aspecto:

```
{
  "_lastChangedAt": {
    "N": "1574469356331"
  },
  "_ttl": {
    "N": "1574472956"
  },
  "_version": {
    "N": "1"
  },
  "author": {
    "S": "Nadia"
  },
  "content": {
    "S": "Hello World"
  },
  "ds_pk": {
    "S": "AppSync-delta-sync-post:2019-11-23"
  },
  "ds_sk": {
    "S": "00:35:56.331:81d36bbb-1579-4efe-92b8-2e3f679f628b:1"
  },
  "id": {
    "S": "81d36bbb-1579-4efe-92b8-2e3f679f628b"
  },
  "title": {
    "S": "My First Post"
  }
}
```

Ahora podemos simular una consulta *Base* que un cliente ejecutará para hidratar su almacén de datos local usando una consulta `syncPosts` como esta:

```
query baseQuery {
  syncPosts(limit: 100, lastSync: null, nextToken: null) {
    items {
      id
      author
      title
      content
      _version
      _lastChangedAt
    }
    startedAt
    nextToken
  }
}
```

El valor devuelto de esta consulta *Base* tiene este aspecto:

```
{
  "data": {
    "syncPosts": {
      "items": [
        {
          "id": "81d36bbb-1579-4efe-92b8-2e3f679f628b",
          "author": "Nadia",
          "title": "My First Post",
          "content": "Hello World",
          "_version": 1,
          "_lastChangedAt": 1574469356331
        }
      ],
      "startedAt": 1574469602238,
      "nextToken": null
    }
  }
}
```

Más adelante, vamos a guardar el valor de `startedAt` para simular una consulta *Delta*, pero antes tenemos que hacer un cambio en nuestra tabla. Vamos a utilizar la mutación `updatePost` para modificar nuestro Post existente:

```
mutation updatePost {
  updatePost(input: {id: "81d36bbb-1579-4efe-92b8-2e3f679f628b", _version: 1, title: "Actually this is my Second Post"}) {
    id
    author
    title
    content
    _version
    _lastChangedAt
    _deleted
  }
}
```

El valor de retorno de esta mutación tendrá el siguiente aspecto:

```
{
  "data": {
    "updatePost": {
      "id": "81d36bbb-1579-4efe-92b8-2e3f679f628b",
      "author": "Nadia",
      "title": "Actually this is my Second Post",
      "content": "Hello World",
      "_version": 2,
      "_lastChangedAt": 1574469851417,
      "_deleted": null
    }
  }
}
```

Si examina el contenido de la tabla *Base* ahora, debería ver el elemento actualizado:

```
{
  "_lastChangedAt": {
    "N": "1574469851417"
  },
  "_version": {
    "N": "2"
  },
  "author": {
    "S": "Nadia"
  },
  "content": {
    "S": "Hello World"
  },
  "id": {
    "S": "81d36bbb-1579-4efe-92b8-2e3f679f628b"
  },
  "title": {
    "S": "Actually this is my Second Post"
  }
}
```

Si examina el contenido de la tabla *Delta* ahora, debería ver dos registros:

1. Un registro de cuando se creó el elemento

1. Un registro de cuando se actualizó el elemento

El nuevo elemento tendrá este aspecto:

```
{
  "_lastChangedAt": {
    "N": "1574469851417"
  },
  "_ttl": {
    "N": "1574473451"
  },
  "_version": {
    "N": "2"
  },
  "author": {
    "S": "Nadia"
  },
  "content": {
    "S": "Hello World"
  },
  "ds_pk": {
    "S": "AppSync-delta-sync-post:2019-11-23"
  },
  "ds_sk": {
    "S": "00:44:11.417:81d36bbb-1579-4efe-92b8-2e3f679f628b:2"
  },
  "id": {
    "S": "81d36bbb-1579-4efe-92b8-2e3f679f628b"
  },
  "title": {
    "S": "Actually this is my Second Post"
  }
}
```

Ahora podemos simular una consulta *Delta* para recuperar las modificaciones que ocurrieron mientras un cliente estaba sin conexión. Utilizaremos el valor `startedAt` devuelto por nuestra consulta *Base* para realizar la solicitud:

```
query delta {
  syncPosts(limit: 100, lastSync: 1574469602238, nextToken: null) {
    items {
      id
      author
      title
      content
      _version
    }
    startedAt
    nextToken
  }
}
```

El valor devuelto de esta consulta *Delta* tendrá este aspecto:

```
{
  "data": {
    "syncPosts": {
      "items": [
        {
          "id": "81d36bbb-1579-4efe-92b8-2e3f679f628b",
          "author": "Nadia",
          "title": "Actually this is my Second Post",
          "content": "Hello World",
          "_version": 2
        }
      ],
      "startedAt": 1574470400808,
      "nextToken": null
    }
  }
}
```