Help us understand the problem. What is going on with this article?

OpenRestyからRedisに問い合わせるAPIのLuaのサンプル

More than 5 years have passed since last update.

Nginxを拡張してLuaが便利なOpenRestyを使って簡単なAPIのサンプルを書いてみます。バックエンドのRedisに問い合わせてJSON形式でレスポンスを返します。LuaのRedisクライアントはlua-resty-redisを使っているようです。Luaで組み込みのプログラムが書けるので、リバースプロキシにも使うOpenRestyのところで、バックエンドのアプリのちょっとしたAPIの差異を吸収することができます。

プロジェクト

今回もサービスのオーケストレーションにはDocker Composeを使います。プロジェクトのディレクトリを作成してdocker-compose.ymlとnginx.confを作成します。

$ cd ~/openresty_apps
$ tree
.
├── docker-compose.yml
└── nginx
    └── nginx.conf

OpenRestyのイメージはtenstartups/openrestyを使います。このイメージでは/entrypointという起動スクリプトがENTRYPOINTに設定されています。nginx.confを編集したあとにHUPを送って再読み込みしたいので、docker-compose.ymlで上書きます。

~/openresty_apps/docker-compose-yml
openresty:
  restart: always
  image: tenstartups/openresty
  ports:
    - "80:80"
  volumes:
    - ./nginx:/etc/nginx
  links:
    - redis
  entrypoint: ["nginx", "-c", "/etc/nginx/nginx.conf"]
redis:
  restart: always
  image: redis
rediscli:
  image: redis
  links:
    - redis

nginx.confで環境変数を読み込むためにenvディレクティブを使い、linksで指定されたRedisnサービスのIPアドレスとポートを設定します。クエリ文字列にuuidを指定します。OpenRestyからRedisに問い合わせて対応するtokenを取得してJSONを返す簡単なサンプルです。

~/openresty_apps/nginx/nginx.conf
daemon off;
worker_processes  1;

env REDIS_PORT_6379_TCP_ADDR;
env REDIS_PORT_6379_TCP_PORT;

events {
    worker_connections  256;
}

http {
    server {
        listen 80;
        access_log /proc/self/fd/1;
        error_log /proc/self/fd/2;

        location /api/v1/tokens {
            default_type text/html;
            content_by_lua '
                local cjson = require "cjson"
                local redis = require "resty.redis"
                local red = redis:new()
                local args = ngx.req.get_uri_args()

                local ok, err = red:connect(os.getenv("REDIS_PORT_6379_TCP_ADDR"), tonumber(os.getenv("REDIS_PORT_6379_TCP_PORT")))

                if not ok then
                    ngx.say("failed to connect: ", err)
                    return
                end

                local res, err = red:get("users:" .. args.uuid)

                if not res then
                    ngx.say("failed to get token: ", err)
                    return
                end

                ngx.header.content_type = "application/json; charset=utf-8"
                ngx.say(cjson.encode({token = res}))
                red:close()
            ';
        }
    }
}

Docker Composeからopenrestyサービスをupします。

$ docker-compose up openresty
docker-compose up openresty
Recreating openrestyapps_redis_1...
Recreating openrestyapps_openresty_1...
Attaching to openrestyapps_openresty_1

依存関係にあるredisサービスも起動しますがrediscliサービスは起動しません。

$ docker-compose ps
      Name             Command             State              Ports
-------------------------------------------------------------------------
openrestyapps_op   nginx -c /etc/ng   Up                 0.0.0.0:80->80/t
enresty_1          inx/nginx.conf                        cp
openrestyapps_re   /entrypoint.sh     Up                 6379/tcp
dis_1              redis-server

redis-cliでレコード作成

rediscliサービスでテスト用のレコードをRedisに作成します。

$ docker-compose run --rm rediscli bash -c 'redis-cli -h $REDIS_PORT_6379_TCP_ADDR set users:123 8Nyo7D9a'
OK
Removing openrestyapps_rediscli_run_1...

getからレコードの作成を確認します。

$ docker-compose run --rm rediscli bash -c 'redis-cli -h $REDIS_PORT_6379_TCP_ADDR get users:123'
"8Nyo7D9a"
Removing openrestyapps_rediscli_run_1...

curlでテスト

openrestyサービスにHUPを送ってnginx.confを再読込します。

$ docker-compose kill -s HUP openresty
Killing openrestyapps_openresty_1...

Dockerホストからcurlを使いJSON形式でtokenが取得できました。

$ curl  "http://localhost/api/v1/tokens?uuid=123"
{"token":"8Nyo7D9a"}
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした