

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.

# Expresiones de condición
<a name="js-aws-appsync-resolver-reference-dynamodb-condition-expressions"></a>

Al mutar objetos en DynamoDB utilizando las operaciones de DynamoDB `PutItem`, `UpdateItem` y `DeleteItem`, puede especificar opcionalmente una expresión de condición que determine si la solicitud se debe atender o no en función del estado del objeto que ya está en DynamoDB antes de ejecutar la operación.

La función AWS AppSync DynamoDB permite especificar una expresión de condición `PutItem` en los objetos de solicitud `DeleteItem` y`UpdateItem`, además, una estrategia a seguir si la condición falla y el objeto no se ha actualizado.

## Ejemplo 1
<a name="js-id19"></a>

El siguiente objeto de solicitud `PutItem` no tiene una expresión de condición. Como resultado, pone un elemento en DynamoDB incluso si ya existe un elemento con la misma clave, lo que permite sobrescribir el elemento existente.

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

## Ejemplo 2
<a name="js-id20"></a>

El siguiente objeto `PutItem` tiene una expresión de condición que permitirá que la operación se complete solo si *no* existe un elemento con la misma clave en DynamoDB.

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

De forma predeterminada, si se produce un error en la comprobación de la condición, la función AWS AppSync DynamoDB proporciona un error para la mutación.

Sin embargo, la función AWS AppSync DynamoDB ofrece algunas funciones adicionales para ayudar a los desarrolladores a gestionar algunos casos extremos comunes:
+ Si las funciones de AWS AppSync DynamoDB pueden determinar que el valor actual de DynamoDB coincide con el resultado deseado, tratarán la operación como si se hubiera realizado correctamente de todos modos.
+ En lugar de devolver un error, puede configurar la función para que invoque una función Lambda personalizada para decidir cómo debe gestionar el error la función de AWS AppSync DynamoDB.

Estos casos se describen con más detalle en la sección de [gestión de un error de comprobación de la condición](#condition-check).

[Para obtener más información sobre las expresiones de condiciones de DynamoDB, consulte la documentación de DynamoDB. ConditionExpressions ](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.ConditionExpressions.html)

## Especificación de una condición
<a name="js-aws-appsync-resolver-reference-dynamodb-condition-specification"></a>

Todos los objetos de solicitud `PutItem`, `UpdateItem` y `DeleteItem` permiten especificar una sección `condition` opcional. Si se omite, no se comprobará ninguna condición. Si se especifica, la condición debe ser true para que la operación se lleve a cabo correctamente.

Las secciones `condition` tienen la siguiente estructura:

```
type ConditionCheckExpression = {
  expression: string;
  expressionNames?: { [key: string]: string};
  expressionValues?: { [key: string]: any};
  equalsIgnore?: string[];
  consistentRead?: boolean;
  conditionalCheckFailedHandler?: {
    strategy: 'Custom' | 'Reject';
    lambdaArn?: string;
  };
};
```

Los campos siguientes especifican la condición:

** `expression` **  
La misma expresión de actualización. Para obtener más información sobre cómo escribir expresiones de condiciones, consulte la documentación de [ ConditionExpressions DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.ConditionExpressions.html). Este campo debe especificarse.

** `expressionNames` **  
Las sustituciones de los marcadores de posición de nombre de atributo de expresión, en forma de pares de clave-valor. La clave corresponde a un marcador de posición de nombre usado en la *expresión*, y el valor tiene que ser una cadena que corresponda al nombre de atributo del elemento en DynamoDB. Este campo es opcional y solo debe rellenarse con las sustituciones de los marcadores de posición de nombre de atributo de expresión que se usen en la *expresión*.

** `expressionValues` **  
Las sustituciones de los marcadores de posición de valor de atributo de expresión, en forma de pares de clave-valor. La clave corresponde a un marcador de posición de valor usado en la expresión y el valor tiene que ser un valor con tipo. Para obtener más información sobre cómo especificar un “valor con tipo”, consulte [Sistema de tipos (mapeo de solicitud)](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-typed-values-request). Este valor debe especificarse. Este campo es opcional y solo debe rellenarse con las sustituciones de los marcadores de posición de valor de atributo de expresión que se usen en la expresión.

Los campos restantes indican a la función AWS AppSync DynamoDB cómo gestionar un error de comprobación de condición:

** `equalsIgnore` **  
Cuando se produce un error en una comprobación de estado al utilizar la `PutItem` operación, la función AWS AppSync DynamoDB compara el elemento que se encuentra actualmente en DynamoDB con el elemento que intentó escribir. Si son iguales, trata la operación como si se hubiera realizado correctamente. Puede usar el `equalsIgnore` campo para especificar una lista de atributos que AWS AppSync debe omitir al realizar la comparación. Por ejemplo, si la única diferencia ha sido un atributo `version`, trata la operación como si se hubiera realizado satisfactoriamente. Este campo es opcional.

** `consistentRead` **  
Cuando se produce un error en una comprobación de estado, AWS AppSync obtiene el valor actual del elemento de DynamoDB mediante una lectura muy coherente. Puede usar este campo para indicar a la función AWS AppSync DynamoDB que utilice en su lugar una lectura eventualmente coherente. Este campo es opcional y de forma predeterminada es `true`.

** `conditionalCheckFailedHandler` **  
En esta sección, puede especificar cómo trata la función AWS AppSync DynamoDB un error de comprobación de condición después de comparar el valor actual de DynamoDB con el resultado esperado. Esta sección es opcional. Si se omite, el valor predeterminado es una estrategia `Reject`.    
** `strategy` **  
La estrategia que adopta la función AWS AppSync DynamoDB después de comparar el valor actual de DynamoDB con el resultado esperado. Este campo es obligatorio y tiene los siguientes valores posibles:    
** `Reject` **  
Se produce un error en la mutación y se agrega un error a la respuesta de GraphQL.  
** `Custom` **  
La función AWS AppSync DynamoDB invoca una función Lambda personalizada para decidir cómo gestionar el error de comprobación de estado. Cuando `strategy` tiene el valor `Custom`, el campo `lambdaArn` debe contener el ARN de la función Lambda que se va a invocar.  
** `lambdaArn` **  
El ARN de la función Lambda que se va a invocar y que determina cómo debe gestionar la función de DynamoDB el error de comprobación de AWS AppSync condición. Este campo solo tiene que especificarse cuando `strategy` tiene el valor `Custom`. Para obtener más información acerca de cómo utilizar esta característica, consulte [Gestión de un error de comprobación de la condición](#condition-check).

## Gestión de un error de comprobación de la condición
<a name="js-aws-appsync-resolver-reference-dynamodb-condition-handling"></a>

Cuando se produce un error en una comprobación de condición, la función AWS AppSync DynamoDB puede transmitir el error de la mutación y el valor actual del objeto mediante la utilidad. `util.appendError` Sin embargo, la función AWS AppSync DynamoDB ofrece algunas funciones adicionales para ayudar a los desarrolladores a gestionar algunos casos extremos comunes:
+ Si las funciones de AWS AppSync DynamoDB pueden determinar que el valor actual de DynamoDB coincide con el resultado deseado, tratarán la operación como si se hubiera realizado correctamente de todos modos.
+ En lugar de devolver un error, puede configurar la función para que invoque una función Lambda personalizada para decidir cómo debe gestionar el error la función de AWS AppSync DynamoDB.

El diagrama de flujo de este proceso es:

![\[Flowchart showing process for transforming requests with mutation attempts and value checks.\]](http://docs.aws.amazon.com/es_es/appsync/latest/devguide/images/DynamoDB-condition-check-failure-handling.png)


### Comprobación del resultado deseado
<a name="js-checking-for-the-desired-result"></a>

Cuando se produce un error en la comprobación de estado, la función AWS AppSync DynamoDB ejecuta una solicitud de `GetItem` DynamoDB para obtener el valor actual del elemento de DynamoDB. De forma predeterminada, utiliza una lectura altamente coherente; sin embargo, esto puede configurarse mediante el campo `consistentRead` en el bloque `condition` y compararlo con el resultado esperado:
+ Para la `PutItem` operación, la función AWS AppSync DynamoDB compara el valor actual con el que intentó escribir, excluyendo todos los atributos incluidos `equalsIgnore` en la comparación. Si los elementos son los mismos, trata la operación como si se hubiera realizado y devuelve el elemento obtenido de DynamoDB. De lo contrario, sigue la estrategia configurada.

  Por ejemplo, si el objeto de solicitud `PutItem` tenía el siguiente aspecto:

  ```
  import { util } from '@aws-appsync/utils';
  export function request(ctx) {
    const { id, name, version} = ctx.args
    return {
      operation: 'PutItem',
      key: util.dynamodb.toMapValues({foo, bar}),
      attributeValues: util.dynamodb.toMapValues({ name, version: version+1 }),
      condition: { 
        expression: "version = :expectedVersion",
        expressionValues: util.dynamodb.toMapValues({':expectedVersion': version}),
        equalsIgnore: ['version']
      }
    };
  }
  ```

  Y el elemento que está actualmente en DynamoDB fuese de la siguiente manera:

  ```
  {
     "id" : { "S" : "1" },
     "name" : { "S" : "Steve" },
     "version" : { "N" : 8 }
  }
  ```

  La función AWS AppSync DynamoDB compararía el elemento que intentaba escribir con el valor actual, comprobaría que la única diferencia era el campo, pero como está configurada para ignorar `version` el campo, considera que `version` la operación se ha realizado correctamente y devuelve el elemento que se ha recuperado de DynamoDB.
+ Para la `DeleteItem` operación, la función AWS AppSync DynamoDB comprueba si DynamoDB ha devuelto un elemento. Si no se devuelve ningún elemento, trata la operación como si se hubiera realizado correctamente. De lo contrario, sigue la estrategia configurada.
+ Para la `UpdateItem` operación, la función AWS AppSync DynamoDB no tiene suficiente información para determinar si el elemento que se encuentra actualmente en DynamoDB coincide con el resultado esperado y, por lo tanto, sigue la estrategia configurada.

Si el estado actual del objeto en DynamoDB es diferente del resultado esperado, la función AWS AppSync DynamoDB sigue la estrategia configurada: rechazar la mutación o invocar una función Lambda para determinar qué hacer a continuación.

### Aplicación de la estrategia de rechazo
<a name="js-following-the-reject-strategy"></a>

Al seguir la `Reject` estrategia, la función AWS AppSync DynamoDB devuelve un error para la mutación.

Por ejemplo, si se recibe la solicitud de mutación siguiente:

```
mutation {
    updatePerson(id: 1, name: "Steve", expectedVersion: 1) {
        Name
        theVersion
    }
}
```

Si el elemento devuelto de DynamoDB tiene un aspecto similar al siguiente:

```
{
   "id" : { "S" : "1" },
   "name" : { "S" : "Steve" },
   "version" : { "N" : 8 }
}
```

Y el controlador de respuestas de función tiene el siguiente aspecto:

```
import { util } from '@aws-appsync/utils';
export function response(ctx) {
  const { version, ...values } = ctx.result;
  const result = { ...values, theVersion: version };
  if (ctx.error) {
    if (error) {
      return util.appendError(error.message, error.type, result, null);
    }
  }
  return result
}
```

La respuesta GraphQL tiene este aspecto:

```
{
  "data": null,
  "errors": [
    {
      "message": "The conditional request failed (Service: AmazonDynamoDBv2; Status Code: 400; Error Code: ConditionalCheckFailedException; Request ID: ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ)"
      "errorType": "DynamoDB:ConditionalCheckFailedException",
      ...
    }
  ]
}
```

Además, si hay algún campo en el objeto devuelto que hayan cumplimentado otros solucionadores y si la mutación se ha efectuado satisfactoriamente, el objeto no se resuelve cuando se devuelve en la sección `error`.

### Aplicación de la estrategia personalizada
<a name="js-following-the-custom-strategy"></a>

Al seguir la `Custom` estrategia, la función AWS AppSync DynamoDB invoca una función Lambda para decidir qué hacer a continuación. La función Lambda selecciona una de las siguientes opciones:
+  `reject` para la mutación. Esto indica a la función AWS AppSync DynamoDB que se comporte como si la estrategia configurada lo `Reject` fuera, devolviendo un error para la mutación y el valor actual del objeto en DynamoDB, tal y como se describe en la sección anterior.
+  `discard` para la mutación. Esto indica a la función AWS AppSync DynamoDB que ignore silenciosamente el error de comprobación de estado y devuelve el valor en DynamoDB.
+  `retry` para la mutación. Esto indica a la función AWS AppSync DynamoDB que vuelva a intentar la mutación con un nuevo objeto de solicitud.

 **La solicitud de invocación Lambda**

La AWS AppSync función DynamoDB invoca la función Lambda especificada en. `lambdaArn` Se utiliza el mismo `service-role-arn` configurado en el origen de datos. La carga de la invocación tiene la siguiente estructura:

```
{
    "arguments": { ... },
    "requestMapping": {... },
    "currentValue": { ... },
    "resolver": { ... },
    "identity": { ... }
}
```

Los campos se definen de la siguiente manera:

** `arguments` **  
Los argumentos de la mutación de GraphQL. Esto es lo mismo que los argumentos disponibles en el objeto de solicitud en `context.arguments`.

** `requestMapping` **  
El objeto de solicitud de esta operación.

** `currentValue` **  
El valor actual del objeto en DynamoDB.

** `resolver` **  
Información sobre el solucionador o la función AWS AppSync .

** `identity` **  
Información sobre el intermediario. Equivale a la información de identidad disponible en el objeto de solicitud en `context.identity`.

Un ejemplo completo de la carga:

```
{
    "arguments": {
        "id": "1",
        "name": "Steve",
        "expectedVersion": 1
    },
    "requestMapping": {
        "version" : "2017-02-28",
        "operation" : "PutItem",
        "key" : {
           "id" : { "S" : "1" }
        },
        "attributeValues" : {
           "name" : { "S" : "Steve" },
           "version" : { "N" : 2 }
        },
        "condition" : {
           "expression" : "version = :expectedVersion",
           "expressionValues" : {
               ":expectedVersion" : { "N" : 1 }
           },
           "equalsIgnore": [ "version" ]
        }
    },
    "currentValue": {
        "id" : { "S" : "1" },
        "name" : { "S" : "Steve" },
        "version" : { "N" : 8 }
    },
    "resolver": {
        "tableName": "People",
        "awsRegion": "us-west-2",
        "parentType": "Mutation",
        "field": "updatePerson",
        "outputType": "Person"
    },
    "identity": {
        "accountId": "123456789012",
        "sourceIp": "x.x.x.x",
        "user": "AIDAAAAAAAAAAAAAAAAAA",
        "userArn": "arn:aws:iam::123456789012:user/appsync"
    }
}
```

 **La respuesta de invocación Lambda** 

La función Lambda puede inspeccionar la carga útil de invocación y aplicar cualquier lógica empresarial para decidir cómo debe gestionar el error la función de AWS AppSync DynamoDB. Existen tres opciones para gestionar el error de comprobación de condición:
+  `reject` para la mutación. La carga de respuesta de esta opción debe tener esta estructura:

  ```
  {
      "action": "reject"
  }
  ```

  Esto indica a la función AWS AppSync DynamoDB que se comporte como si la estrategia configurada lo `Reject` fuera, devolviendo un error para la mutación y el valor actual del objeto en DynamoDB, tal y como se describe en la sección anterior.
+  `discard` para la mutación. La carga de respuesta de esta opción debe tener esta estructura:

  ```
  {
      "action": "discard"
  }
  ```

  Esto indica a la función AWS AppSync DynamoDB que ignore silenciosamente el error de comprobación de estado y devuelve el valor en DynamoDB.
+  `retry` para la mutación. La carga de respuesta de esta opción debe tener esta estructura:

  ```
  {
      "action": "retry",
      "retryMapping": { ... }
  }
  ```

  Esto indica a la función AWS AppSync DynamoDB que vuelva a intentar la mutación con un nuevo objeto de solicitud. La estructura de la sección `retryMapping` depende de la operación de DynamoDB y es un subconjunto del objeto de solicitud completo de esa operación.

  Para `PutItem`, la sección `retryMapping` tiene la siguiente estructura. Para obtener una descripción del `attributeValues` campo, consulte. [PutItem](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-mapping-template-reference-dynamodb.html#aws-appsync-resolver-mapping-template-reference-dynamodb-putitem)

  ```
  {
      "attributeValues": { ... },
      "condition": {
          "equalsIgnore" = [ ... ],
          "consistentRead" = true
      }
  }
  ```

  Para `UpdateItem`, la sección `retryMapping` tiene la siguiente estructura. Para obtener una descripción de la `update` sección, consulte [UpdateItem](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-mapping-template-reference-dynamodb.html#aws-appsync-resolver-mapping-template-reference-dynamodb-updateitem).

  ```
  {
      "update" : {
          "expression" : "someExpression"
          "expressionNames" : {
              "#foo" : "foo"
          },
          "expressionValues" : {
              ":bar" : ... typed value
          }
      },
      "condition": {
          "consistentRead" = true
      }
  }
  ```

  Para `DeleteItem`, la sección `retryMapping` tiene la siguiente estructura.

  ```
  {
      "condition": {
          "consistentRead" = true
      }
  }
  ```

  No hay forma de especificar otra operación o clave en la que trabajar. La función AWS AppSync DynamoDB solo permite reintentos de la misma operación en el mismo objeto. Asimismo, la sección `condition` no permite especificar un `conditionalCheckFailedHandler`. Si se produce un error en el reintento, la AWS AppSync función DynamoDB sigue la estrategia. `Reject`

A continuación se muestra un ejemplo de función Lambda para tratar una solicitud `PutItem` sin éxito. La lógica de negocio examina quién realizó la llamada. Si la realizó `jeffTheAdmin`, vuelve a intentar realizar la solicitud, actualizando `version` y `expectedVersion` desde el elemento actualmente en DynamoDB. De lo contrario, rechaza la mutación.

```
exports.handler = (event, context, callback) => {
    console.log("Event: "+ JSON.stringify(event));

    // Business logic goes here.

    var response;
    if ( event.identity.user == "jeffTheAdmin" ) {
        response = {
            "action" : "retry",
            "retryMapping" : {
                "attributeValues" : event.requestMapping.attributeValues,
                "condition" : {
                    "expression" : event.requestMapping.condition.expression,
                    "expressionValues" : event.requestMapping.condition.expressionValues
                }
            }
        }
        response.retryMapping.attributeValues.version = { "N" : event.currentValue.version.N + 1 }
        response.retryMapping.condition.expressionValues[':expectedVersion'] = event.currentValue.version

    } else {
        response = { "action" : "reject" }
    }

    console.log("Response: "+ JSON.stringify(response))
    callback(null, response)
};
```