

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á.

# Usando o Aurora Serverless v2 com AWS AppSync
<a name="tutorial-rds-resolvers"></a>

Conecte sua API GraphQL aos bancos de dados Aurora Serverless usando o. AWS AppSync Essa integração permite a você executar instruções SQL por meio de consultas, mutações e assinaturas do GraphQL, oferecendo uma maneira flexível de interagir com os dados relacionais.

**nota**  
Este tutorial usa a Região `US-EAST-1`.

**Benefícios**
+ Integração perfeita entre GraphQL e bancos de dados relacionais
+ Capacidade de realizar operações SQL por meio de interfaces GraphQL
+ Escalabilidade da tecnologia sem servidor com Aurora Serverless v2
+ Acesso seguro aos dados por meio do AWS Secrets Manager
+ Proteção contra injeção de SQL por meio da limpeza de entradas
+ Recursos de consulta flexíveis, inclusive operações de filtragem e alcance

**Casos de uso comuns**
+ Criação de aplicações escaláveis com requisitos de dados relacionais
+ Para criar APIs isso, é necessário tanto a flexibilidade do GraphQL quanto os recursos do banco de dados SQL
+ Gerenciamento das operações de dados por meio de mutações e consultas do GraphQL
+ Implementação dos padrões de acesso seguro ao banco de dados

Neste tutorial, você aprenderá os itens a seguir.
+ Configurar o cluster do Aurora Serverless v2
+ Habilitar a funcionalidade da API Data
+ Criar e configurar estruturas do banco de dados
+ Definir esquemas do GraphQL para operações do banco de dados
+ Implementar resolvedores para consultas e mutações
+ Proteger o acesso a dados por meio da limpeza de entradas indicada
+ Executar operações de banco de dados variadas por meio de interfaces GraphQL

**Topics**
+ [Configuração do cluster do banco de dados](#create-cluster)
+ [Ativar API de dados](#enable-data-api)
+ [Criar banco de dados e tabela](#create-database-and-table)
+ [Esquema do GraphQL](#graphql-schema)
+ [Conectar a API às operações do banco de dados](#configuring-resolvers)
+ [Modificar os dados por meio da API](#run-mutations)
+ [Recuperar os dados](#run-queries)
+ [Proteger o acesso a dados](#input-sanitization)

## Configuração do cluster do banco de dados
<a name="create-cluster"></a>

**Antes de adicionar uma fonte de dados do Amazon RDS AWS AppSync, você deve primeiro habilitar uma API de dados em um cluster Aurora Serverless v2 e configurar um segredo usando. *AWS Secrets Manager*** Você pode criar um cluster do Aurora Serverless v2 usando Aurora AWS CLI:

```
aws rds create-db-cluster \
    --db-cluster-identifier appsync-tutorial \
    --engine aurora-mysql \
    --engine-version 8.0 \
    --serverless-v2-scaling-configuration MinCapacity=0,MaxCapacity=1 \
    --master-username USERNAME \
    --master-user-password COMPLEX_PASSWORD \
    --enable-http-endpoint
```

Isso retornará um ARN para o cluster.

Depois de criar o cluster, você deverá adicionar uma instância do Aurora Serverless v2 usando o comando a seguir.

```
aws rds create-db-instance \
    --db-cluster-identifier appsync-tutorial \
    --db-instance-identifier appsync-tutorial-instance-1 \
    --db-instance-class db.serverless \
    --engine aurora-mysql
```

**nota**  
Estes endpoints levam tempo para serem ativados. Você pode consultar o status no console do Amazon RDS na guia **Conectividade e segurança** do cluster. Você também pode verificar o status do seu cluster com o AWS CLI comando a seguir.   

```
aws rds describe-db-clusters \
    --db-cluster-identifier appsync-tutorial \
    --query "DBClusters[0].Status"
```

Você pode criar um *segredo* usando o AWS Secrets Manager console ou AWS CLI com um arquivo de entrada, como o seguinte, usando o `USERNAME` e `COMPLEX_PASSWORD` da etapa anterior.

```
{
    "username": "USERNAME",
    "password": "COMPLEX_PASSWORD"
}
```

Passe isso como um parâmetro para AWS CLI:

```
aws secretsmanager create-secret --name HttpRDSSecret --secret-string file://creds.json --region us-east-1
```

Isso retornará um ARN para o segredo.

 **Anote o ARN do seu** cluster Aurora Serverless e Secret para uso posterior no AppSync console ao criar uma fonte de dados.

## Ativar API de dados
<a name="enable-data-api"></a>

Você pode ativar a API de dados em seu cluster [seguindo as instruções na documentação do RDS](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/data-api.html). A API de dados deve ser ativada antes de ser adicionada como fonte de AppSync dados.

## Criar banco de dados e tabela
<a name="create-database-and-table"></a>

Depois de ativar sua API de dados, você pode garantir que ela funcione com o comando `aws rds-data execute-statement` na AWS CLI. Isso garantirá que seu cluster Aurora Serverless seja configurado corretamente antes de adicioná-lo à sua API. AppSync Primeiro crie um banco de dados chamado *TESTDB* com o parâmetro `--sql` da seguinte forma:

```
aws rds-data execute-statement --resource-arn "arn:aws:rds:us-east-1:123456789000:cluster:http-endpoint-test" \
--schema "mysql"  --secret-arn "arn:aws:secretsmanager:us-east-1:123456789000:secret:testHttp2-AmNvc1"  \
--region us-east-1 --sql "create DATABASE TESTDB"
```

Se isso for executado sem erro, inclua uma tabela com o comando *create table*:

```
aws rds-data execute-statement --resource-arn "arn:aws:rds:us-east-1:123456789000:cluster:http-endpoint-test" \
 --schema "mysql"  --secret-arn "arn:aws:secretsmanager:us-east-1:123456789000:secret:testHttp2-AmNvc1" \
 --region us-east-1 \
 --sql "create table Pets(id varchar(200), type varchar(200), price float)" --database "TESTDB"
```

Se tudo tiver sido executado sem problemas, você poderá adicionar o cluster como fonte de dados na sua AppSync API.

## Esquema do GraphQL
<a name="graphql-schema"></a>

Agora que sua API de dados do Aurora Serverless está funcionando com uma tabela, criaremos um esquema do GraphQL e anexaremos resolvedores para executar mutações e assinaturas. Crie uma nova API no AWS AppSync console, navegue até a página **Esquema** e insira o seguinte:

```
type Mutation {
    createPet(input: CreatePetInput!): Pet
    updatePet(input: UpdatePetInput!): Pet
    deletePet(input: DeletePetInput!): Pet
}

input CreatePetInput {
    type: PetType
    price: Float!
}

input UpdatePetInput {
id: ID!
    type: PetType
    price: Float!
}

input DeletePetInput {
    id: ID!
}

type Pet {
    id: ID!
    type: PetType
    price: Float
}

enum PetType {
    dog
    cat
    fish
    bird
    gecko
}

type Query {
    getPet(id: ID!): Pet
    listPets: [Pet]
    listPetsByPriceRange(min: Float, max: Float): [Pet]
}

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

 **Salve** seu esquema e navegue até a página **Fontes de dados** e crie uma nova fonte de dados. Selecione **Banco de dados relacional** para o tipo de fonte de dados e forneça um nome amigável. Use o nome do banco de dados que você criou na última etapa, bem como o **ARN do cluster** em que você o criou. Para a **função**, você pode AppSync criar uma nova função ou criar uma com uma política semelhante à abaixo:

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

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "rds-data:BatchExecuteStatement",
                "rds-data:BeginTransaction",
                "rds-data:CommitTransaction",
                "rds-data:ExecuteStatement",
                "rds-data:RollbackTransaction"
            ],
            "Resource": [
                "arn:aws:rds:us-east-1:111122223333:cluster:mydbcluster",
                "arn:aws:rds:us-east-1:111122223333:cluster:mydbcluster:*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "secretsmanager:GetSecretValue"
            ],
            "Resource": [
            "arn:aws:secretsmanager:us-east-1:111122223333:secret:mysecret",
            "arn:aws:secretsmanager:us-east-1:111122223333:secret:mysecret:*"
            ]
        }
    ]
}
```

------

Observe que há duas **instruções** nesta política que você está concedendo acesso à função. O primeiro **recurso** é seu cluster Aurora Serverless e o segundo é seu ARN. AWS Secrets Manager Você precisará fornecer **AMBOS** ARNs na configuração da fonte de AppSync dados antes de clicar em **Criar**.

Passe isso como um parâmetro para AWS CLI o.

```
aws secretsmanager create-secret \
  --name HttpRDSSecret \
  --secret-string file://creds.json \
  --region us-east-1
```

Isso retornará um ARN para o segredo. Anote o ARN do seu cluster e segredo sem servidor do Aurora para mais tarde ao criar uma fonte de dados no console. AWS AppSync 

### Criar a estrutura do banco de dados
<a name="create-database-and-table"></a>

Depois de ativar sua API de dados, você pode garantir que ela funcione com o comando `aws rds-data execute-statement` na AWS CLI. Isso garantirá que seu cluster Aurora Serverless v2 seja configurado corretamente antes de adicioná-lo à sua API. AWS AppSync Primeiro, crie um banco de dados chamado *TESTDB* com o parâmetro `--sql` da maneira a seguir.

```
aws rds-data execute-statement \
                --resource-arn "arn:aws:rds:us-east-1:111122223333:cluster:appsync-tutorial" \
                --secret-arn "arn:aws:secretsmanager:us-east-1:111122223333:secret:appsync-tutorial-rds-secret"  \
                --region us-east-1 \
                --sql "create DATABASE TESTDB"
```

Se isso for executado sem erros, adicione uma tabela com o comando *create table*.

```
aws rds-data execute-statement \
      --resource-arn "arn:aws:rds:us-east-1:111122223333:cluster:http-endpoint-test" \
      --secret-arn "arn:aws:secretsmanager:us-east-1:111122223333:secret:testHttp2-AmNvc1" \
      --region us-east-1 \
      --sql "create table Pets(id varchar(200), type varchar(200), price float)" \
      --database "TESTDB"
```

### Projetar a interface da API
<a name="graphql-schema"></a>

Depois que a API Data do Aurora Serverless v2 estiver funcionando com uma tabela, criaremos um esquema do GraphQL e anexaremos resolvedores para realizar mutações e assinaturas. Crie uma nova API no AWS AppSync console, navegue até a página **Esquema** no console e insira o seguinte.

```
type Mutation {
        createPet(input: CreatePetInput!): Pet
        updatePet(input: UpdatePetInput!): Pet
        deletePet(input: DeletePetInput!): Pet
    }
    
    input CreatePetInput {
        type: PetType
        price: Float!
    }
    
    input UpdatePetInput {
        id: ID!
        type: PetType
        price: Float!
    }
    
    input DeletePetInput {
        id: ID!
    }
    
    type Pet {
        id: ID!
        type: PetType
        price: Float
    }
    
    enum PetType {
        dog
        cat
        fish
        bird
        gecko
    }
    
    type Query {
        getPet(id: ID!): Pet
        listPets: [Pet]
        listPetsByPriceRange(min: Float, max: Float): [Pet]
    }
    
    schema {
        query: Query
        mutation: Mutation
    }
```

 **Salve** seu esquema e navegue até a página **Fontes de dados** e crie uma nova fonte de dados. Escolha **Banco de dados relacional** para o tipo **Fonte de dados** e dê um nome amigável. Use o nome do banco de dados que você criou na última etapa, bem como o **ARN do cluster** em que você o criou. Para a **função**, você pode AWS AppSync criar uma nova função ou criar uma com uma política semelhante à seguinte.

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

****  

```
{
        "Version":"2012-10-17",		 	 	 
        "Statement": [
            {
                "Effect": "Allow",
                "Action": [
                    "rds-data:BatchExecuteStatement",
                    "rds-data:BeginTransaction",
                    "rds-data:CommitTransaction",
                    "rds-data:ExecuteStatement",
                    "rds-data:RollbackTransaction"
                ],
                "Resource": [
                    "arn:aws:rds:us-east-1:111122223333:cluster:mydbcluster",
                    "arn:aws:rds:us-east-1:111122223333:cluster:mydbcluster:*"
                ]
            },
            {
                "Effect": "Allow",
                "Action": [
                    "secretsmanager:GetSecretValue"
                ],
                "Resource": [
                "arn:aws:secretsmanager:us-east-1:111122223333:secret:mysecret",
                "arn:aws:secretsmanager:us-east-1:111122223333:secret:mysecret:*"
                ]
            }
        ]
    }
```

------

Observe que há duas **instruções** nesta política que você está concedendo acesso à função. O primeiro **recurso** é seu cluster Aurora Serverless v2 e o segundo é seu ARN. AWS Secrets Manager Você precisará fornecer **AMBOS** ARNs na configuração da fonte de AWS AppSync dados antes de clicar em **Criar**.

## Conectar a API às operações do banco de dados
<a name="configuring-resolvers"></a>

Agora que temos um esquema do GraphQL válido e uma fonte de dados RDS, você pode anexar resolvedores aos campos do GraphQL ao esquema. Nossa API oferecerá os seguintes recursos:

1. criar um animal de estimação usando o campo *Mutation.createPet*

1. atualizar um animal de estimação usando o campo *Mutation.updatePet*

1. excluir um animal de estimação usando o campo *Mutation.deletePet*

1. obter um único animal de estimação usando o campo *Query.getPet*

1. listar tudo usando o campo *Query.listPets*

1. liste animais de estimação em uma faixa de preço usando o *Query. listPetsByPriceRange*campo

### Mutation.createPet
<a name="mutation-createpet"></a>

No editor de esquemas no AWS AppSync console, no lado direito, escolha **Attach Resolver** for`createPet(input: CreatePetInput!): Pet`. Escolha a fonte de dados do RDS. Na seção **modelo de mapeamento de solicitação**, adicione o seguinte modelo:

```
#set($id=$utils.autoId())
{
"version": "2018-05-29",
    "statements": [
        "insert into Pets VALUES (:ID, :TYPE, :PRICE)",
        "select * from Pets WHERE id = :ID"
    ],
    "variableMap": {
        ":ID": "$ctx.args.input.id",
        ":TYPE": $util.toJson($ctx.args.input.type),
        ":PRICE": $util.toJson($ctx.args.input.price)
    }
}
```

O sistema executa instruções SQL sequencialmente, com base na ordem na matriz de **instruções**. Os resultados retornarão na mesma ordem. Como essa é uma mutação, executaremos uma instrução *select* depois de *insert* para recuperar os valores confirmados a fim de preencher o modelo de mapeamento de respostas do GraphQL.

Na seção **modelo de mapeamento de resposta**, adicione o seguinte modelo:

```
$utils.toJson($utils.rds.toJsonObject($ctx.result)[1][0])
```

Como as *instruções* têm duas consultas SQL, precisamos especificar o segundo resultado na matriz que retorna do banco de dados com: `$utils.rds.toJsonString($ctx.result))[1][0])`.

### Mutation.updatePet
<a name="mutation-updatepet"></a>

No editor de esquemas no AWS AppSync console, escolha **Anexar resolvedor** para`updatePet(input: UpdatePetInput!): Pet`. Escolha a **fonte de dados do RDS**. Na seção **Modelo de mapeamento de solicitações**, adicione o modelo a seguir.

```
{
"version": "2018-05-29",
    "statements": [
        $util.toJson("update Pets set type=:TYPE, price=:PRICE WHERE id=:ID"),
        $util.toJson("select * from Pets WHERE id = :ID")
    ],
    "variableMap": {
        ":ID": "$ctx.args.input.id",
        ":TYPE": $util.toJson($ctx.args.input.type),
        ":PRICE": $util.toJson($ctx.args.input.price)
    }
}
```

Na seção **Modelo de mapeamento de respostas**, adicione o modelo a seguir.

```
$utils.toJson($utils.rds.toJsonObject($ctx.result)[1][0])
```

### Mutation.deletePet
<a name="mutation-deletepet"></a>

No editor de esquemas no AWS AppSync console, escolha **Anexar resolvedor** para`deletePet(input: DeletePetInput!): Pet`. Escolha a **fonte de dados do RDS**. Na seção **Modelo de mapeamento de solicitações**, adicione o modelo a seguir.

```
{
"version": "2018-05-29",
    "statements": [
        $util.toJson("select * from Pets WHERE id=:ID"),
        $util.toJson("delete from Pets WHERE id=:ID")
    ],
    "variableMap": {
        ":ID": "$ctx.args.input.id"
    }
}
```

Na seção **Modelo de mapeamento de respostas**, adicione o modelo a seguir.

```
$utils.toJson($utils.rds.toJsonObject($ctx.result)[0][0])
```

### Query.getPet
<a name="query-getpet"></a>

Agora que as mutações estão criadas para o esquema, conectamos as três consultas para demonstrar como obter itens individuais, listas e aplicar a filtragem SQL. No **editor de esquemas** no AWS AppSync console, escolha **Anexar resolvedor** para`getPet(id: ID!): Pet`. Escolha a **fonte de dados do RDS**. Na seção **Modelo de mapeamento de solicitações**, adicione o modelo a seguir.

```
{
"version": "2018-05-29",
        "statements": [
            $util.toJson("select * from Pets WHERE id=:ID")
    ],
    "variableMap": {
        ":ID": "$ctx.args.id"
    }
}
```

Na seção **modelo de mapeamento de resposta**, adicione o seguinte modelo:

```
$utils.toJson($utils.rds.toJsonObject($ctx.result)[0][0])
```

### Query.listPets
<a name="query-listpets"></a>

No editor de esquemas no AWS AppSync console, no lado direito, escolha **Attach Resolver** for`getPet(id: ID!): Pet`. Escolha a **fonte de dados do RDS**. Na seção **Modelo de mapeamento de solicitações**, adicione o modelo a seguir.

```
{
    "version": "2018-05-29",
    "statements": [
        "select * from Pets"
    ]
}
```

Na seção **Modelo de mapeamento de respostas**, adicione o modelo a seguir.

```
$utils.toJson($utils.rds.toJsonObject($ctx.result)[0])
```

### Consulta. listPetsByPriceRange
<a name="query-listpetsbypricerange"></a>

No editor de esquemas no AWS AppSync console, no lado direito, escolha **Attach Resolver** for`getPet(id: ID!): Pet`. Escolha a **fonte de dados do RDS**. Na seção **Modelo de mapeamento de solicitações**, adicione o modelo a seguir.

```
{
    "version": "2018-05-29",
    "statements": [
            "select * from Pets where price > :MIN and price < :MAX"
    ],

    "variableMap": {
        ":MAX": $util.toJson($ctx.args.max),
        ":MIN": $util.toJson($ctx.args.min)
    }
}
```

Na seção **modelo de mapeamento de resposta**, adicione o seguinte modelo:

```
$utils.toJson($utils.rds.toJsonObject($ctx.result)[0])
```

## Modificar os dados por meio da API
<a name="run-mutations"></a>

Agora que você configurou todos os seus resolvedores com instruções SQL e conectou a API do GraphQL à API de dados do Aurora Serverless, é possível começar a realizar mutações e consultas. No AWS AppSync console, escolha a guia **Consultas** e digite o seguinte para criar um animal de estimação:

```
mutation add {
    createPet(input : { type:fish, price:10.0 }){
        id
        type
        price
    }
}
```

A resposta deve conter o *id*, o *tipo* e o *preço* da seguinte forma:

```
{
  "data": {
    "createPet": {
      "id": "c6fedbbe-57ad-4da3-860a-ffe8d039882a",
      "type": "fish",
      "price": "10.0"
    }
  }
}
```

Você pode modificar este item executando a mutação *updatePet*:

```
mutation update {
    updatePet(input : {
        id: ID_PLACEHOLDER,
        type:bird,
        price:50.0
    }){
        id
        type
        price
    }
}
```

Observe que usamos o *id* que foi retornado da operação *createPet* anteriormente. Esse será um valor único para o seu registro, já que o resolvedor utilizou `$util.autoId()`. Você pode excluir um registro de maneira semelhante:

```
mutation delete {
    deletePet(input : {id:ID_PLACEHOLDER}){
        id
        type
        price
    }
}
```

Crie alguns registros com a primeira mutação com valores diferentes para *preço* e execute algumas consultas.

## Recuperar os dados
<a name="run-queries"></a>

Ainda na guia **Consultas** do console, use a instrução a seguir para listar todos os registros criados por você.

```
query allpets {
    listPets {
        id
        type
        price
    }
}
```

Aproveite o predicado SQL *WHERE* que estava `where price > :MIN and price < :MAX` em nosso modelo de mapeamento para o *Query. listPetsByPriceRange*com a seguinte consulta do GraphQL:

```
query petsByPriceRange {
    listPetsByPriceRange(min:1, max:11) {
        id
        type
        price
    }
}
```

Você só deve ver registros com um *preço* acima de US\$1 1 ou abaixo de US\$1 10. Por fim, é possível realizar consultas para recuperar registros individuais da seguinte maneira:

```
query onePet {
    getPet(id:ID_PLACEHOLDER){
        id
        type
        price
    }
}
```

## Proteger o acesso a dados
<a name="input-sanitization"></a>

A injeção de SQL é uma vulnerabilidade de segurança em aplicações de banco de dados. Isso ocorre quando invasores inserem um código SQL mal-intencionado por meio dos campos de entrada do usuário. Isso pode permitir acesso não autorizado aos dados do banco de dados. É recomendável validar e limpar com cuidado todas as entradas do usuário antes do processamento usando `variableMap` para proteção contra ataques de injeção de SQL. Se mapas de variáveis não forem usados, você será responsável por limpar os argumentos das operações do GraphQL. Uma maneira de fazer isso é fornecer etapas de validação específicas de entrada no modelo de mapeamento de solicitação antes da execução de uma instrução SQL em relação à API de dados. Vamos ver como podemos modificar o modelo de mapeamento de solicitação do exemplo `listPetsByPriceRange`. Em vez de contar apenas com a entrada do usuário, você pode fazer o seguinte:

```
#set($validMaxPrice = $util.matches("\d{1,3}[,\\.]?(\\d{1,2})?",$ctx.args.maxPrice))

#set($validMinPrice = $util.matches("\d{1,3}[,\\.]?(\\d{1,2})?",$ctx.args.minPrice))


#if (!$validMaxPrice || !$validMinPrice)
    $util.error("Provided price input is not valid.")
#end
{
    "version": "2018-05-29",
    "statements": [
            "select * from Pets where price > :MIN and price < :MAX"
    ],

    "variableMap": {
        ":MAX": $util.toJson($ctx.args.maxPrice),
        ":MIN": $util.toJson($ctx.args.minPrice)
    }
}
```

Outra maneira de proteger contra entradas invasivas ao executar resolvedores em relação à API de dados é usar instruções preparadas junto com o procedimento armazenado e entradas parametrizadas. Por exemplo, no resolvedor para `listPets`, defina o seguinte procedimento que executa *select* como uma instrução preparada:

```
CREATE PROCEDURE listPets (IN type_param VARCHAR(200))
  BEGIN
     PREPARE stmt FROM 'SELECT * FROM Pets where type=?';
     SET @type = type_param;
     EXECUTE stmt USING @type;
     DEALLOCATE PREPARE stmt;
  END
```

Crie isso na instância do Aurora Serverless v2.

```
aws rds-data execute-statement --resource-arn "arn:aws:rds:us-east-1:xxxxxxxxxxxx:cluster:http-endpoint-test" \
--schema "mysql"  --secret-arn "arn:aws:secretsmanager:us-east-1:xxxxxxxxxxxx:secret:httpendpoint-xxxxxx"  \
--region us-east-1  --database "DB_NAME" \
--sql "CREATE PROCEDURE listPets (IN type_param VARCHAR(200)) BEGIN PREPARE stmt FROM 'SELECT * FROM Pets where type=?'; SET @type = type_param; EXECUTE stmt USING @type; DEALLOCATE PREPARE stmt; END"
```

O código de resolvedor resultante para listPets foi simplificado, pois agora simplesmente chamamos o procedimento armazenado. No mínimo, qualquer entrada de string deve ter aspas simples [com caracteres de escape](#escaped).

```
#set ($validType = $util.isString($ctx.args.type) && !$util.isNullOrBlank($ctx.args.type))
#if (!$validType)
    $util.error("Input for 'type' is not valid.", "ValidationError")
#end

{
    "version": "2018-05-29",
    "statements": [
        "CALL listPets(:type)"
    ]
    "variableMap": {
        ":type": $util.toJson($ctx.args.type.replace("'", "''"))
    }
}
```

### Uso das strings de escape
<a name="escaped"></a>

Use aspas simples para marcar o início e o fim dos literais de string em uma instrução SQL; por exemplo, `'some string value'`. Para permitir que valores de string com um ou mais caracteres de aspas simples (`'`) sejam usados em uma string, cada um deve ser substituído por duas aspas simples (`''`). Por exemplo, se a string de entrada for `Nadia's dog`, você deverá inserir caracteres de escape nela para a instrução SQL, como

```
update Pets set type='Nadia''s dog' WHERE id='1'
```