# Primeiros passos com o Azion Runtime

Este guia leva você pela sua primeira function no Azion Runtime, do código até uma requisição ao domínio após o deploy.

- Crie um projeto de function em JavaScript com a Azion CLI.
- Escreva o handler no formato ES Modules recomendado, `export default { fetch(request, env, ctx) }`.
- Chame uma Web API e leia os metadados da requisição, uma API da Azion.
- Execute a function com `azion dev`, depois faça o deploy dela e compare as duas respostas.

A function retorna quatro valores em JSON. `EdgeRuntime` indica onde o código roda, `URL` e `crypto.randomUUID()` são [Web APIs](/pt-br/documentacao/devtools/runtime/api-reference/javascript/), e `request.metadata` traz os [metadados da requisição](/pt-br/documentacao/devtools/runtime/api-reference/metadata/) que a Azion adiciona a toda requisição.

---

## Pré-requisitos

- A Azion CLI, instalada e com login feito. Para a configuração, consulte [Primeiros passos com a Azion CLI](/pt-br/documentacao/devtools/cli/primeiros-passos/).
- Node.js e npm. A CLI executa o bundler da Azion com `npx` para fazer o build do projeto.
- `curl` na sua máquina.

---

## Crie o projeto

Crie um projeto chamado `my-runtime-function` com a CLI:

```bash
azion init --name my-runtime-function
```

O comando faz cinco perguntas. Selecione o preset *Javascript* e o template *Hello World*, digite `Y` para instalar as dependências e digite `n` para o servidor local e para o deploy. Você executa os dois depois de escrever o handler. O comando confirma o projeto:

```text
Your application my-runtime-function was initialized successfully
```

A entrada da function é `index.js`, na raiz do novo diretório `my-runtime-function`. O template escreve esse arquivo no formato mais antigo, `export default main`, que o build informa como obsoleto. Para todos os formatos que o runtime aceita, consulte [Handlers](/pt-br/documentacao/devtools/runtime/api-reference/handlers/).

---

## Escreva o handler

Substitua o conteúdo de `index.js` por este handler:

```javascript
export default {
  async fetch(request, env, ctx) {
    const url = new URL(request.url);

    return Response.json({
      runtime: EdgeRuntime,
      path: url.pathname,
      requestId: crypto.randomUUID(),
      country: request.metadata?.geoip_country_name ?? null,
    });
  },
};
```

O runtime chama `fetch` uma vez por requisição:

- `request` é a [Request](/pt-br/documentacao/devtools/runtime/api-reference/request/) recebida, e `request.metadata` traz os dados de GeoIP e de rede da requisição.
- `env` contém as variáveis de ambiente, e `ctx` traz `waitUntil()`. Este handler não usa nenhum dos dois.
- `Response.json()` cria uma [Response](/pt-br/documentacao/devtools/runtime/api-reference/response/) com o objeto como corpo JSON e `content-type: application/json`.

O optional chaining em `request.metadata?.` mantém o handler funcionando com `azion dev`, em que a requisição não traz metadados.

---

## Execute a function localmente

Vá para o diretório do projeto e inicie o servidor de desenvolvimento local:

```bash
cd my-runtime-function
azion dev
```

O comando faz o build da function e a serve na porta 3333:

```text
[Azion] [Build] › ℹ  info      Using preset: javascript
[Azion] [Pre-Build] › ℹ  info      Starting pre-build...
[Azion] [Pre-Build] › ℹ  info      Pre-build completed successfully
[Azion] [Build] › ℹ  info      Using preset default entry: index.js
[Azion] [Build] › ℹ  info      Starting build...
[Azion] [Build] › ✔  success   Build completed successfully
[Azion] [Post-Build] › ℹ  info      Starting post-build...
[Azion] [Post-Build] › ✔  success   Post-build completed successfully
[Azion] [Server] › ✔  success   Function running on port 0.0.0.0:3333, url: http://localhost:3333
[Azion] [Server] › ℹ  info      Initial scan complete. Ready for changes.
```

O build não mostra aviso de obsolescência, porque o handler usa o formato ES Modules. Em um segundo terminal, faça uma requisição a um caminho:

```bash
curl -s -i 'http://localhost:3333/hello'
```

A function responde com JSON:

```text
HTTP/1.1 200 OK
content-type: application/json
Date: Thu, 01 Jan 2026 12:00:00 GMT
Connection: keep-alive
Keep-Alive: timeout=5
Transfer-Encoding: chunked

{"runtime":"edge-runtime","path":"/hello","requestId":"9b2138b1-02f0-433c-aee5-9442142996b2","country":null}
```

Localmente, `EdgeRuntime` é `edge-runtime` e `country` é `null`, porque o `azion dev` não adiciona metadados à requisição. Para parar o servidor, pressione `Ctrl+C`. Para tudo o que muda entre o `azion dev` e uma function após o deploy, consulte [Como o Azion Runtime funciona](/pt-br/documentacao/devtools/runtime/como-funciona/#comportamento-local-e-apos-o-deploy).

---

## Faça o deploy da function

No diretório `my-runtime-function`, faça o deploy do projeto:

```bash
azion deploy
```

O comando envia o projeto, faz o build, cria a function, a aplicação e o workload, e mostra o domínio do workload:

```text
Running deploy command
Uploading source files

Upload completed successfully!
…
Your Application was deployed successfully

To visualize your application access the Domain: https://<your-azion-domain>
Your application is being deployed to all Azion Locations and it might take a few minutes.
```

O primeiro deploy pode levar vários minutos para responder em todas as localidades. Até uma localidade ter a function, ela responde `404` com uma página de título `There's nothing here yet`. Espere e tente de novo antes de diagnosticar o deploy.

---

## Faça uma requisição à function após o deploy

Faça uma requisição ao mesmo caminho no domínio que o `azion deploy` mostrou. Substitua `<your-azion-domain>` por esse domínio:

```bash
curl -s -i 'https://<your-azion-domain>/hello'
```

Após o deploy, a function responde com as mesmas chaves:

```text
HTTP/2 200 
date: Thu, 01 Jan 2026 12:00:00 GMT
content-type: application/json
x-azion-request-id: 0123456789abcdef0123456789abcdef
x-azion-edge-location: <edge-location>
alt-svc: h3=":443"; ma=86400

{"runtime":"azion","path":"/hello","requestId":"1aa1a614-a0ca-4291-93a1-66fa1c57ebc9","country":"Brazil"}
```

Após o deploy, `EdgeRuntime` é `azion`, e `country` traz o país do cliente que enviou a requisição, a partir dos metadados da requisição. `requestId` muda a cada requisição. A function roda no Azion Runtime e responde no domínio do workload.

Para mudar a function, edite `index.js` e execute `azion deploy` de novo no diretório `my-runtime-function`. Os deploys seguintes levam cerca de dois minutos para responder em todas as localidades.

---

## Próximos passos

- [Como o Azion Runtime funciona](/pt-br/documentacao/devtools/runtime/como-funciona.md): O modelo de execução, os formatos de handler, o bundler e o que muda com o azion dev.
- [Web APIs](/pt-br/documentacao/devtools/runtime/api-reference/javascript.md): Todas as Web APIs que o runtime oferece, do fetch e dos streams à Web Crypto.
- [APIs do Node.js](/pt-br/documentacao/devtools/runtime/node.md): Os módulos do Node.js que o build resolve e como cada um se comporta após o deploy.
- [Primeiros passos com Functions](/pt-br/documentacao/plataforma/functions/primeiros-passos.md): Crie uma function no Azion Console e execute-a em uma aplicação.
