---
title: "Guia de Estilo de Codificação do OpenResty - API7.ai"
description: "O guia de estilo do OpenResty contém regras gerais sobre \"como escrever\" código OpenResty, Lua e NGINX."
url: "https://api7.ai/pt/learning-center/openresty/openresty-coding-style-guide"
---

# Guia de Estilo de Codificação do OpenResty

API7.ai

December 15, 2022

[OpenResty (NGINX + Lua)](https://api7.ai/learning-center/openresty)

Muitas linguagens de desenvolvimento possuem suas especificações de codificação para informar aos desenvolvedores algumas convenções no campo, manter o estilo do código escrito consistente e evitar algumas armadilhas comuns. O PEP 8 do Python é um excelente exemplo disso, e quase todos os desenvolvedores Python já leram essa especificação de codificação escrita pelos autores do Python.

O OpenResty ainda não possui sua própria especificação de codificação, e alguns desenvolvedores são repetidamente revisados e solicitados a alterar o estilo de seu código após enviarem PRs, o que consome muito tempo e esforço que poderiam ser evitados.

Existem duas ferramentas de Lint no OpenResty que podem ajudá-lo a detectar automaticamente o estilo do código: `luacheck` e `lj-releng`. A primeira é uma ferramenta de Lint comum no mundo Lua e OpenResty, e a segunda é uma ferramenta de Lint escrita em `Perl` pelo próprio OpenResty.

No meu caso, instalei o plugin `luacheck` no editor VS Code para ter uma ferramenta de sugestão automática ao escrever código; e no CI de um projeto, executo ambas as ferramentas, por exemplo:

```
luacheck -q lua

./utils/lj-releng lua/*.lua lua/apisix/*.lua
```

Afinal, mais uma ferramenta para testes nunca é demais.

No entanto, essas duas ferramentas são mais focadas em detectar variáveis globais, comprimento por linha e outros estilos de código mais básicos, o que ainda está longe do nível detalhado do Python PEP 8, e não há documentação para você consultar.

Portanto, hoje, com base na minha experiência em projetos de código aberto relacionados ao OpenResty, compilei a documentação de estilo de codificação do OpenResty. Esta especificação também é consistente com o estilo de código de alguns gateways de API como APISIX e Kong.

## Indentação

No OpenResty, usamos 4 espaços como marcadores de indentação, embora o Lua não exija essa sintaxe. Aqui estão dois exemplos de códigos incorretos e corretos.

```
--Não
if a then
ngx.say("hello")
end
```

```
--Sim
if a then
    ngx.say("hello")
end
```

Para conveniência, podemos simplificar a operação alterando a tabulação para 4 espaços no editor que você está usando.

## Espaço

Em ambos os lados do operador, é necessário um espaço para separá-los. A seguir estão dois exemplos de códigos incorretos e corretos.

```
--Não
local i=1
local s    =    "apisix"
```

```
--Sim
local i = 1
local s = "apisix"
```

## Linha em branco

Muitos desenvolvedores trazem convenções de desenvolvimento de outras linguagens para o OpenResty, como adicionar um ponto e vírgula ao final de uma linha:

```
--Não
if a then
    ngx.say("hello");
end;
```

Mas, na verdade, adicionar ponto e vírgula faz o código Lua parecer muito feio, o que é desnecessário. Além disso, você não deve transformar várias linhas de código em uma única linha para economizar linhas e ser conciso. Fazer isso deixará você sem saber qual seção do código está com erro ao localizar o problema.

```
--Não
if a then ngx.say("hello") end
```

```
--Sim
if a then
    ngx.say("hello")
end
```

Além disso, as funções precisam ser separadas por duas linhas em branco.

```
--Não
local function foo()
end
local function bar()
end
```

```
--Sim
local function foo()
end

local function bar()
end
```

Se houver vários ramos `if elseif`, eles também precisam ser separados por uma linha em branco.

```
--Não
if a == 1 then
    foo()
elseif a== 2 then
    bar()
elseif a == 3 then
    run()
else
    error()
end
```

```
--Sim
if a == 1 then
    foo()

elseif a== 2 then
    bar()

elseif a == 3 then
    run()

else
    error()
end
```

## Comprimento máximo por linha

Cada linha não deve exceder 80 caracteres; se exceder, precisamos quebrar a linha e alinhar. E ao alinhar as quebras de linha, precisamos refletir a correspondência entre as linhas superiores e inferiores. Para o exemplo abaixo, o argumento da função na segunda linha deve estar à direita do parêntese esquerdo na primeira linha.

```
--Não
return limit_conn_new("plugin-limit-conn", conf.conn, conf.burst, conf.default_conn_delay)
```

```
--Sim
return limit_conn_new("plugin-limit-conn", conf.conn, conf.burst,
                    conf.default_conn_delay)
```

Se for o alinhamento de concatenação de strings, precisamos colocar `..` na próxima linha.

```
--Não
return limit_conn_new("plugin-limit-conn" ..  "plugin-limit-conn" ..
                    "plugin-limit-conn")
```

```
--Sim
return limit_conn_new("plugin-limit-conn" .. "plugin-limit-conn"
                    .. "plugin-limit-conn")
```

## Variável

Este ponto também foi enfatizado várias vezes em artigos anteriores: devemos sempre usar variáveis locais em vez de variáveis globais.

```
--Não
i = 1
s = "apisix"
```

```
--Sim
local i = 1
local s = "apisix"
```

Quanto à nomenclatura das variáveis, o estilo `snake_case` deve ser usado.

```
--Não
local IndexArr = 1
local str_Name = "apisix"
```

```
--Sim
local index_arr = 1
local str_name = "apisix"
```

Para constantes, por outro lado, o estilo `all-caps` deve ser usado.

```
--Não
local max_int = 65535
local server_name = "apisix"

--Sim
local MAX_INT = 65535
local SERVER_NAME = "apisix"
```

## Tabela

No OpenResty, usamos `table.new` para pré-alocar a tabela.

```
--Não
local t = {}
for i = 1, 100 do
   t[i] = i
 end
```

```
--Sim
local new_tab = require "table.new"
 local t = new_tab(100, 0)
 for i = 1, 100 do
   t[i] = i
 end
```

Além disso, observe que você nunca deve usar `nil` no array, e se precisar usar nulo, use `ngx.null` para indicar isso.

```
--Não
local t = {1, 2, nil, 3}

--Sim
local t = {1, 2, ngx.null, 3}
```

## String

Nunca concatene strings em um caminho de código quente.

```
--Não
local s = ""
for i = 1, 100000 do
    s = s .. "a"
end
```

```
--Sim
local t = {}
for i = 1, 100000 do
    t[i] = "a"
end
local s =  table.concat(t, "")
```

## Função

A nomenclatura das funções também segue o `snake_case`.

```
--Não
local function testNginx()
end
```

```
--Sim
local function test_nginx()
end
```

E a função deve retornar o mais cedo possível.

```
--Não
local function check(age, name)
    local ret = true
    if age < 20 then
        ret = false
    end

    if name == "a" then
        ret = false
    end
    -- fazer algo mais
    return ret
```

```
--Sim
local function check(age, name)
    if age < 20 then
        return false
    end

    if name == "a" then
        return false
    end
    -- fazer algo mais
    return true
```

## Módulo

Todas as bibliotecas `require` devem ser `local`izadas:

```
--Não
local function foo()
    local ok, err = ngx.timer.at(delay, handler)
end
```

```
--Sim
local timer_at = ngx.timer.at

local function foo()
    local ok, err = timer_at(delay, handler)
end
```

Para consistência de estilo, `require` e `ngx` também precisam ser `local`izados:

```
--Não
local core = require("apisix.core")
local timer_at = ngx.timer.at

local function foo()
    local ok, err = timer_at(delay, handler)
end
```

```
--Sim
local ngx = ngx
local require = require
local core = require("apisix.core")
local timer_at = ngx.timer.at

local function foo()
    local ok, err = timer_at(delay, handler)
end
```

## Tratamento de erros

Para funções que retornam com informações de erro, a informação de erro deve ser julgada e processada:

```
--Não
local sock = ngx.socket.tcp()
local ok = sock:connect("www.google.com", 80)
ngx.say("conectado com sucesso ao google!")
```

```
--Sim
local sock = ngx.socket.tcp()
local ok, err = sock:connect("www.google.com", 80)
if not ok then
    ngx.say("falha ao conectar ao google: ", err)
    return
end
ngx.say("conectado com sucesso ao google!")
```

E no caso de funções escritas por você mesmo, a informação de erro deve ser retornada como um segundo parâmetro no formato de string:

```
--Não
local function foo()
    local ok, err = func()
    if not ok then
        return false
    end
    return true
end
```

```
--Não
local function foo()
    local ok, err = func()
    if not ok then
        return false, {msg = err}
    end
    return true
end
```

```
--Sim
local function foo()
    local ok, err = func()
    if not ok then
        return false, "falha ao chamar func(): " .. err
    end
    return true
end
```

## Resumo

Esta é uma versão inicial do guia de estilo de codificação, e vamos disponibilizá-lo no GitHub para atualizações e manutenções contínuas. Você é bem-vindo para compartilhar esta especificação para que mais usuários do OpenResty possam se envolver.

Share article link

Share

Related Posts

[![FAQ do OpenResty | Como o OpenResty é usado na prática](https://static.api7.ai/uploads/2023/02/12/jbv9M0zi_Hello%20World%20in%20OpenResty%20%283%29.png)](https://api7.ai/learning-center/openresty/faq-5)

## [FAQ do OpenResty | Como o OpenResty é usado na prática](https://api7.ai/learning-center/openresty/faq-5)

[![Parte 3: Como Construir um API Gateway de Microservices Usando OpenResty](https://static.api7.ai/uploads/2023/02/07/3XJXY9Jy_45.png)](https://api7.ai/learning-center/openresty/how-to-build-a-microservices-api-gateway-part-3)

## [Parte 3: Como Construir um API Gateway de Microservices Usando OpenResty](https://api7.ai/learning-center/openresty/how-to-build-a-microservices-api-gateway-part-3)

Table of Contents

- [Indentação](#indenta%C3%A7%C3%A3o)
- [Espaço](#espa%C3%A7o)
- [Linha em branco](#linha-em-branco)
- [Comprimento máximo por linha](#comprimento-m%C3%A1ximo-por-linha)
- [Variável](#vari%C3%A1vel)
- [Tabela](#tabela)
- [String](#string)
- [Função](#fun%C3%A7%C3%A3o)
- [Módulo](#m%C3%B3dulo)
- [Tratamento de erros](#tratamento-de-erros)
- [Resumo](#resumo)
