---
title: "OpenResty Coding Style Guide - API7.ai"
description: "Der OpenResty Style Guide enthält allgemeine Regeln darüber, „wie man“ OpenResty-, Lua- und NGINX-Code schreibt."
url: "https://api7.ai/de/learning-center/openresty/openresty-coding-style-guide"
---

# OpenResty Coding Style Guide

API7.ai

December 15, 2022

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

Viele Entwicklungssprachen haben ihre eigenen Codierungsrichtlinien, um Entwicklern einige Konventionen in diesem Bereich mitzuteilen, den Stil des geschriebenen Codes konsistent zu halten und einige häufige Fallstricke zu vermeiden. Pythons PEP 8 ist ein hervorragendes Beispiel dafür, und fast alle Python-Entwickler haben diese von den Autoren von Python geschriebene Codierungsrichtlinie gelesen.

OpenResty hat noch keine eigene Codierungsrichtlinie, und einige Entwickler werden wiederholt überprüft und aufgefordert, ihren Codierungsstil nach der Einreichung von PRs zu ändern, was viel Zeit und Mühe kostet, die vermieden werden könnte.

Es gibt zwei Lint-Tools in OpenResty, die Ihnen helfen können, den Codierungsstil automatisch zu überprüfen: `luacheck` und `lj-releng`. Ersteres ist ein gängiges Lint-Tool in der Lua- und OpenResty-Welt, und letzteres ist ein in `Perl` geschriebenes Lint-Tool von OpenResty selbst.

Ich selbst installiere das `luacheck`-Plugin im VS Code-Editor, damit ich ein Tool habe, das mir beim Schreiben von Code automatisch Vorschläge macht; und im CI eines Projekts führe ich beide Tools aus, z.B.

```
luacheck -q lua

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

Schließlich ist ein zusätzliches Tool zum Testen nie eine schlechte Sache.

Diese beiden Tools beziehen sich jedoch mehr auf die Erkennung von globalen Variablen, der Zeilenlänge und anderen grundlegendsten Codierungsstilen, die noch weit vom detaillierten Niveau von Python PEP 8 entfernt sind, und es gibt keine Dokumentation, auf die Sie sich beziehen können.

Daher habe ich heute basierend auf meiner Erfahrung in OpenResty-bezogenen Open-Source-Projekten die OpenResty-Codierungsstil-Dokumentation zusammengefasst. Diese Spezifikation stimmt auch mit dem Codierungsstil einiger API-Gateways wie APISIX und Kong überein.

## Einrückung

In OpenResty verwenden wir 4 Leerzeichen als Einrückungsmarkierungen, obwohl Lua keine solche Syntax erfordert. Hier sind zwei Beispiele für falschen und korrekten Code.

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

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

Der Einfachheit halber können wir den Vorgang vereinfachen, indem wir die Tabulatortaste in dem von Ihnen verwendeten Editor in 4 Leerzeichen ändern.

## Leerzeichen

Auf beiden Seiten des Operators ist ein Leerzeichen erforderlich, um sie zu trennen. Die folgenden Beispiele zeigen falschen und korrekten Code.

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

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

## Leerzeile

Viele Entwickler bringen Entwicklungskonventionen aus anderen Sprachen nach OpenResty, wie z.B. das Hinzufügen eines Semikolons am Ende einer Zeile:

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

Aber tatsächlich macht das Hinzufügen von Semikolons Lua-Code sehr hässlich, was unnötig ist. Außerdem sollten Sie nicht mehrere Codezeilen in eine einzige Zeile umwandeln, um Zeilen zu sparen und prägnant zu sein. Dies lässt Sie im Unklaren, welcher Codeabschnitt fehlerhaft ist, wenn Sie den Fehler lokalisieren.

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

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

Darüber hinaus müssen die Funktionen durch zwei Leerzeilen getrennt werden.

```
--Nein
local function foo()
end
local function bar()
end
```

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

local function bar()
end
```

Wenn es mehrere `if elseif`-Zweige gibt, müssen diese ebenfalls durch eine Leerzeile getrennt werden.

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

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

elseif a== 2 then
    bar()

elseif a == 3 then
    run()

else
    error()
end
```

## Maximale Zeilenlänge

Jede Zeile sollte 80 Zeichen nicht überschreiten; wenn sie dies tut, müssen wir einen Zeilenumbruch durchführen und ausrichten. Und beim Ausrichten von Zeilenumbrüchen müssen wir die Entsprechung zwischen den oberen und unteren Zeilen widerspiegeln. Für das folgende Beispiel sollte das Argument der Funktion in der zweiten Zeile rechts von der öffnenden Klammer in der ersten Zeile stehen.

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

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

Wenn es sich um die Ausrichtung von verketteten Zeichenfolgen handelt, müssen wir `..` in die nächste Zeile setzen.

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

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

## Variable

Dieser Punkt wurde auch in früheren Artikeln mehrmals betont: Wir sollten immer lokale Variablen anstelle von globalen Variablen verwenden.

```
--Nein
i = 1
s = "apisix"
```

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

Was die Benennung von Variablen betrifft, sollte der `snake_case`-Stil verwendet werden.

```
--Nein
local IndexArr = 1
local str_Name = "apisix"
```

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

Für Konstanten hingegen sollte der `all-caps`-Stil verwendet werden.

```
--Nein
local max_int = 65535
local server_name = "apisix"

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

## Tabelle

In OpenResty verwenden wir `table.new`, um die Tabelle vorab zuzuweisen.

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

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

Außerdem ist zu beachten, dass Sie `nil` im Array nicht verwenden dürfen, und wenn Sie unbedingt null verwenden müssen, verwenden Sie `ngx.null`, um dies anzuzeigen.

```
--Nein
local t = {1, 2, nil, 3}

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

## Zeichenfolge

Verkettet niemals Zeichenfolgen auf einem Hot-Code-Pfad.

```
--Nein
local s = ""
for i = 1, 100000 do
    s = s .. "a"
end
```

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

## Funktion

Die Benennung von Funktionen folgt ebenfalls `snake_case`.

```
--Nein
local function testNginx()
end
```

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

Und die Funktion sollte so früh wie möglich zurückkehren.

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

    if name == "a" then
        ret = false
    end
    -- do something else
    return ret
```

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

    if name == "a" then
        return false
    end
    -- do something else
    return true
```

## Modul

Alle `require`-Bibliotheken müssen `local`isiert werden:

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

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

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

Für die Konsistenz des Stils müssen auch `require` und `ngx` `local`isiert werden:

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

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

```
--Ja
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
```

## Fehlerbehandlung

Für Funktionen, die mit Fehlerinformationen zurückkehren, müssen die Fehlerinformationen beurteilt und verarbeitet werden:

```
--Nein
local sock = ngx.socket.tcp()
local ok = sock:connect("www.google.com", 80)
ngx.say("successfully connected to google!")
```

```
--Ja
local sock = ngx.socket.tcp()
local ok, err = sock:connect("www.google.com", 80)
if not ok then
    ngx.say("failed to connect to google: ", err)
    return
end
ngx.say("successfully connected to google!")
```

Und im Fall von selbst geschriebenen Funktionen sollen die Fehlerinformationen als zweiter Parameter im String-Format zurückgegeben werden:

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

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

```
--Ja
local function foo()
    local ok, err = func()
    if not ok then
        return false, "failed to call func(): " .. err
    end
    return true
end
```

## Zusammenfassung

Dies ist eine erste Version des Codierungsstil-Leitfadens, und wir werden ihn auf GitHub zur Verfügung stellen, um ihn kontinuierlich zu aktualisieren und zu pflegen. Sie sind eingeladen, diese Spezifikation zu teilen, damit mehr OpenResty-Benutzer daran teilnehmen können.

Share article link

Share

Related Posts

[![OpenResty FAQ | Wie OpenResty in der Praxis eingesetzt wird](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)

## [OpenResty FAQ | Wie OpenResty in der Praxis eingesetzt wird](https://api7.ai/learning-center/openresty/faq-5)

[![Teil 3: Wie man ein Microservices API Gateway mit OpenResty erstellt](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)

## [Teil 3: Wie man ein Microservices API Gateway mit OpenResty erstellt](https://api7.ai/learning-center/openresty/how-to-build-a-microservices-api-gateway-part-3)

Table of Contents

- [Einrückung](#einr%C3%BCckung)
- [Leerzeichen](#leerzeichen)
- [Leerzeile](#leerzeile)
- [Maximale Zeilenlänge](#maximale-zeilenl%C3%A4nge)
- [Variable](#variable)
- [Tabelle](#tabelle)
- [Zeichenfolge](#zeichenfolge)
- [Funktion](#funktion)
- [Modul](#modul)
- [Fehlerbehandlung](#fehlerbehandlung)
- [Zusammenfassung](#zusammenfassung)
