LoginSignup
10
7

More than 5 years have passed since last update.

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

Last updated at Posted at 2015-05-18

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"}
10
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
7