きっかけ
最近、小学生を中心にプログラミングを教える機会があり、その中でRoblox Studioによるゲーム開発に取り組んでいる子がいました。
Roblox Studio はLua言語でゲームを作成するため、質問に答える際などにLuaがある程度扱えないと困るということで触ってみました。
僕は新しい言語を学ぶ際によくポーカーの役判定ロジックを作成するので、今回もそうしています。
Luaを用いてAPIを作成する方法を調べたところ、OpenResty というフレームワークでできそうだったため、OpenRestyを利用しています。
先に感想
- LuaはRubyとJavaScriptの中間のような印象。書き味はRubyっぽい。一方でいわゆるclassはなく、すべてテーブルで作る点はJavaScriptっぽい。
- 正直Tableの使い方はまだよくわかってない。
- Nginxを拡張する選択肢としてのOpenRestyを知れたのは良かった。
成果物
github.com 勢いで作ったので汚いのは許してください。
以下実装周り
環境構築
Dockerfile
FROM openresty/openresty:alpine COPY nginx.conf /usr/local/openresty/nginx/conf/nginx.conf COPY lua/ /usr/local/openresty/nginx/lua/ EXPOSE 8080 CMD ["openresty", "-g", "daemon off;"]
OpenRestyのイメージを利用すればOK。ただしluarocksというLuaのパッケージマネージャーは含まれていないため、別途ライブラリが必要な場合は openresty:alpine-fat
イメージを利用します。後述の単体テストでは openresty:alpine-fat
を利用しています。
docker-compose.yaml
services: openresty: build: context: . dockerfile: Dockerfile ports: - "8082:8080" volumes: - ./nginx.conf:/usr/local/openresty/nginx/conf/nginx.conf - ./lua/:/usr/local/openresty/nginx/lua/
8082番なのは、その時他のアプリケーションで8080, 8081が埋まっていたからというだけの理由です。
実装
nginx.conf
worker_processes 1; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; keepalive_timeout 15; # 読み込むLuaファイルのパス lua_package_path '/usr/local/openresty/nginx/lua/?.lua;;'; server { listen 8080; server_name localhost; # キャッシュを無効にすることで、毎回リクエストを処理する(実質ホットロード) lua_code_cache off; # API location /api/v1/draw { content_by_lua_file /usr/local/openresty/nginx/lua/handler/draw.lua; } } }
最初のスクリプト
local function handle_request() ngx.say("Hello World!") end handle_request()
実行
docker-compose up -d openresty
curl localhost:8082/api/v1/draw
ユニットテスト
Luaのユニットテストはbustedというライブラリがデファクトっぽかったのでそちらを利用しました。
bustedを利用するにはluarocksでインストールする必要がありますが、 openresty/openresty:alpine
イメージにluarocksは含まれていません。個別にインストールしようとしてもうまくいかなかったため、dockerhubを参考に openresty/openresty:alpine-fat
を利用しました。
DockerfileTest
# luarocksを使いたいためfatを指定 # https://hub.docker.com/r/openresty/openresty#luarocks FROM openresty/openresty:alpine-fat RUN /usr/local/openresty/luajit/bin/luarocks install busted COPY nginx.conf /usr/local/openresty/nginx/conf/nginx.conf COPY lua/ /usr/local/openresty/nginx/lua/ WORKDIR /usr/local/openresty/nginx/lua CMD ["busted", "."]
docker-compose.yaml
services: test: build: context: . dockerfile: DockerfileTest volumes: - ./lua:/usr/local/openresty/nginx/lua command: ["busted", "."]
実行
docker-compose up -d test