---
name: azion-gerencie-dados-de-chave-valor-em-uma-funcao
description: >-
  Armazene, leia e exclua keys em um namespace do KV Store a partir de uma função, com metadata, valores binários, streams e vários namespaces.
---

# Gerencie dados de chave-valor em uma função

Você armazena, lê e exclui keys em um namespace do [KV Store](/pt-br/documentacao/plataforma/kv-store/) a partir de uma [função](/pt-br/documentacao/plataforma/functions/), com o cliente `Azion.KV`. Todos os exemplos desta página abrem o namespace com `await Azion.KV.open(name)`: o construtor é privado e não existe namespace padrão.

Criar o namespace em si é uma tarefa da Azion API, e uma função não faz isso. Para mais informações, consulte [Namespaces](/pt-br/documentacao/plataforma/kv-store/namespaces/).

---

## Pré-requisitos

- Uma função que você pode editar. Para criar uma, consulte [Primeiros passos com Functions](/pt-br/documentacao/plataforma/functions/primeiros-passos/).
- Uma aplicação na qual a função está instanciada. Para vincular a função a uma aplicação, consulte [Instancie uma função em uma aplicação](/pt-br/documentacao/guias/desenvolvimento-de-aplicacoes/primeiros-passos/instanciar-functions/).
- Um namespace do KV Store, criado pela Azion API. Para criar um, consulte [Namespaces](/pt-br/documentacao/plataforma/kv-store/namespaces/).

---

## Crie a função

O cliente é um global do Azion Runtime, portanto o código o alcança sem linha de import e sem credencial. Para criar a função que contém um dos exemplos abaixo:

1. **Abra a página Functions**

   Acesse [Azion Console](https://console.azion.com/) > **Products Menu** > **Libraries** > **Functions**.

2. **Selecione + Function**

3. **Nomeie a função**

   Insira um nome para a função. Por exemplo: `kv-store-handler`.

4. **Cole o código na aba Code**

   Na aba **Code**, substitua o código de exemplo por um dos exemplos desta página e substitua `my-namespace` pelo seu namespace.

5. **Selecione Save**

A função é salva. Ela responde a uma requisição assim que uma regra do [Rules Engine](/pt-br/documentacao/plataforma/applications/rules-engine/) executa sua instância na aplicação.

---

## Armazene um valor

`put` cria uma key e substitui o value de uma key que já existe, portanto uma única chamada cobre os dois casos. Uma string é armazenada como está, um objeto é serializado em JSON e um terceiro argumento carrega `metadata` e um prazo de expiração. Para armazenar três keys em uma invocação:

```javascript
export default {
  async fetch(request, env, ctx) {
    const kv = await Azion.KV.open('my-namespace');

    await kv.put('greeting', 'Hello, World!');

    // Um objeto é serializado em JSON, portanto não precisa de chamada stringify.
    await kv.put('user-preferences', {
      theme: 'dark',
      language: 'en',
      notifications: true,
    });

    // metadata viaja junto do value; expirationTtl expira a key após 3600 segundos.
    await kv.put('session-token', 'abc123xyz', {
      metadata: { userId: 'user-42' },
      expirationTtl: 3600,
    });

    return new Response('Values stored', { status: 201 });
  },
};
```

O handler grava três keys e responde `201`. Para todas as opções que `put` aceita, consulte [Cliente KV](/pt-br/documentacao/devtools/runtime/api-reference/kv-store/).

---

## Leia um valor

`get` lê uma key e retorna o value no tipo que seu segundo argumento nomeia, que por padrão é `text`. Uma key que o namespace não contém retorna `null`, portanto o handler verifica esse caso em vez de capturar um erro. Para ler uma string, um objeto e uma key que pode estar ausente:

```javascript
export default {
  async fetch(request, env, ctx) {
    const kv = await Azion.KV.open('my-namespace');

    const greeting = await kv.get('greeting', 'text');
    const preferences = await kv.get('user-preferences', 'json');

    if (greeting === null) {
      return new Response('Key not found', { status: 404 });
    }

    return new Response(JSON.stringify({ greeting, preferences }), {
      headers: { 'Content-Type': 'application/json' },
      status: 200,
    });
  },
};
```

O handler responde `404` quando `greeting` está ausente e, caso contrário, retorna os dois valores em um único corpo JSON. Uma key que o namespace não guarda cai no ramo do `null` em vez de lançar um erro, e é por isso que a verificação é um teste de igualdade e não um `try`.

---

## Leia várias keys de uma vez

Um array como primeiro argumento de `get` lê várias keys em uma chamada e retorna um objeto simples indexado pelo nome da key. Uma key que o namespace não contém aparece nesse objeto com o value `null`. Para gravar três keys e ler quatro:

```javascript
export default {
  async fetch(request, env, ctx) {
    const kv = await Azion.KV.open('my-namespace');

    await kv.put('user-1', 'Alice');
    await kv.put('user-2', 'Bob');
    await kv.put('user-3', 'Charlie');

    const users = await kv.get(['user-1', 'user-2', 'user-3', 'user-4'], 'text');

    // { "user-1": "Alice", "user-2": "Bob", "user-3": "Charlie", "user-4": null }

    return new Response(JSON.stringify(users), {
      headers: { 'Content-Type': 'application/json' },
      status: 200,
    });
  },
};
```

As três gravações endereçam três keys diferentes, e `user-4` retorna como `null` porque o namespace não guarda nenhuma key com esse nome. A forma de array aceita somente `text` e `json`: qualquer outro tipo de retorno lança `INVALID_MULTIPLE_GET_RETURN_TYPE`.

---

## Leia um valor com seu metadata

`getWithMetadata` retorna um objeto que carrega `value` e `metadata`, portanto uma única chamada lê os dois. O metadata é o que a gravação passou na opção `metadata`. Para armazenar uma key com metadata e ler o par de volta:

```javascript
export default {
  async fetch(request, env, ctx) {
    const kv = await Azion.KV.open('my-namespace');

    await kv.put('session', 'active-session-data', {
      metadata: {
        createdAt: new Date().toISOString(),
        userId: 'user-42',
      },
    });

    const result = await kv.getWithMetadata('session', 'text');

    return new Response(JSON.stringify(result), {
      headers: { 'Content-Type': 'application/json' },
      status: 200,
    });
  },
};
```

O handler retorna `result.value` e `result.metadata` no mesmo corpo da resposta.

---

## Exclua uma key

`delete` remove uma key e não aceita a forma de array, portanto várias keys são removidas com uma chamada cada. Uma leitura antes da exclusão informa ao handler quais das keys o namespace contém. Para excluir duas keys e responder `404` quando ele não contém nenhuma das duas:

```javascript
export default {
  async fetch(request, env, ctx) {
    const kv = await Azion.KV.open('my-namespace');
    const keys = ['session-token', 'session-token-2'];

    try {
      const found = await kv.get(keys, 'text');
      const present = keys.filter((key) => found[key] !== null);

      if (present.length === 0) {
        return new Response('Key not found', { status: 404 });
      }

      await Promise.all(present.map((key) => kv.delete(key)));

      return new Response(`Deleted ${present.length} keys`, { status: 200 });
    } catch (error) {
      return new Response(error.message, { status: 500 });
    }
  },
};
```

O handler responde `200` com o número de keys que removeu, `404` quando o namespace não contém nenhuma das duas keys e `500` carregando a mensagem de uma chamada que foi rejeitada.

---

## Armazene e leia dados binários

`put` aceita um `ArrayBuffer`, e `arrayBuffer` como tipo de retorno de `get` lê os bytes de volta. `TextEncoder` e `TextDecoder` convertem entre uma string e esse buffer. Para armazenar uma string como bytes e decodificá-la na saída:

```javascript
export default {
  async fetch(request, env, ctx) {
    const kv = await Azion.KV.open('my-namespace');

    const binaryData = new TextEncoder().encode('Binary content here').buffer;
    await kv.put('binary-key', binaryData);

    const retrieved = await kv.get('binary-key', 'arrayBuffer');
    const decoded = new TextDecoder('utf-8').decode(retrieved);

    return new Response(decoded, {
      headers: { 'Content-Type': 'text/plain' },
      status: 200,
    });
  },
};
```

O handler retorna a string decodificada, que é o texto que a gravação codificou.

---

## Leia um valor como stream

`stream` como tipo de retorno devolve um `ReadableStream` em vez do value montado, portanto um value grande chega à resposta sem que o handler o retenha. Uma key ausente ainda retorna `null`, portanto o handler verifica antes de construir a resposta. Para passar um value diretamente para o corpo da resposta:

```javascript
export default {
  async fetch(request, env, ctx) {
    const kv = await Azion.KV.open('my-namespace');

    const stream = await kv.get('large-content', 'stream');

    if (stream === null) {
      return new Response('Key not found', { status: 404 });
    }

    return new Response(stream, {
      headers: { 'Content-Type': 'application/octet-stream' },
      status: 200,
    });
  },
};
```

O handler responde `404` quando a key está ausente e, caso contrário, transmite o value como corpo da resposta.

---

## Use um namespace específico

`Azion.KV.open` vincula um cliente ao namespace que ele nomeia, portanto uma função que alcança dois namespaces abre dois clientes. O mesmo nome de key em dois namespaces endereça dois valores separados. Para gravar e ler uma key em cada um de dois namespaces:

```javascript
export default {
  async fetch(request, env, ctx) {
    const productionKv = await Azion.KV.open('production-data');
    const stagingKv = await Azion.KV.open('staging-data');

    await productionKv.put('config', 'production-value');
    await stagingKv.put('config', 'staging-value');

    const production = await productionKv.get('config', 'text');
    const staging = await stagingKv.get('config', 'text');

    return new Response(JSON.stringify({ production, staging }), {
      headers: { 'Content-Type': 'application/json' },
      status: 200,
    });
  },
};
```

Cada key `config` pertence ao seu próprio namespace, portanto nenhuma das gravações sobrescreve a outra. Um nome que não pertence a nenhum namespace da conta lança `NotFound: KV namespace "staging-data" does not exist`.

---

## Próximos passos

- [Cliente KV](/pt-br/documentacao/devtools/runtime/api-reference/kv-store.md): Todos os métodos, opções, tipos de retorno e erros do cliente Azion.KV.
- [Namespaces](/pt-br/documentacao/plataforma/kv-store/namespaces.md): Crie, liste e recupere um namespace pela Azion API.
- [Boas práticas](/pt-br/documentacao/plataforma/kv-store/boas-praticas.md): As recomendações a seguir antes da primeira key entrar.
- [Solução de problemas](/pt-br/documentacao/plataforma/kv-store/solucao-de-problemas.md): O que uma chamada do KV Store reporta quando falha e o que fazer a respeito.
