Chalice入門（APIgateway+Lambda）

２プロジェクト連続でのリリースがあり、15日に記事が書けませんでした。すみません。。。
[qiita advent-calendar 2017 aws-lambda](https://qiita.com/advent-calendar/2017/aws-lambda)
の12/15の記事となります。

最近は私の会社もアドベントカレンダーを始めていて、
そこでもChaliceを書いたのですが、Chaliceとは、サーバーレスのフレームワークです。
[github](https://github.com/aws/chalice)
[docs](http://chalice.readthedocs.io/en/latest/api.html)

Pythonで、簡単にAPIが作成できます。
今回の記事は、初めてLambdaでAPI書いてみる、人向けの記事になります。

# 環境と前提条件
## 環境
PC：Macbook Pro
OS:macOS High Sierra
Python:3.6.3

## 前提条件
・AWSCLIがセットアップされていること
・Python3がインストールされていること
・pipがインストールされていること

# chaliceのインストール

さくっと以下のコマンドでインストールしましょう。

```:shell
$ sudo pip install chalice
```

# chaliceプロジェクトの作成
適当なディレクトリに移動して、「new-project」します。
そうすると、サンプルアプリのapp.pyとrequirementsが生成されます。

```:shell
$ cd ~/Project 
$ chalice new-project qiita-advent
$ cd qiita-advent
$ tree -a
.
├── .chalice
│   └── config.json
├── .gitignore
├── app.py
└── requirements.txt
```


```python3:app.py
from chalice import Chalice

app = Chalice(app_name='qiita-advent')


@app.route('/')
def index():
    return {'hello': 'world'}


# The view function above will return {"hello": "world"}
# whenever you make an HTTP GET request to '/'.
#
# Here are a few more examples:
#
# @app.route('/hello/{name}')
# def hello_name(name):
#    # '/hello/james' -> {"hello": "james"}
#    return {'hello': name}
#
# @app.route('/users', methods=['POST'])
# def create_user():
#     # This is the JSON body the user sent in their POST request.
#     user_as_json = app.current_request.json_body
#     # We'll echo the json body back to the user in a 'user' key.
#     return {'user': user_as_json}
#
# See the README documentation for more examples.
#
```

# 自作ライブラリを追加する場合
[docs](http://chalice.readthedocs.io/en/latest/api.html)にも記載があるのですが、
以下のように**chalicelib**へ格納するのがいいみたいです。

```:shell
$ tree -a
.
├── .chalice
│   └── config.json
├── .gitignore
├── app.py
├── chalicelib
│   ├── __init__.py
│   └── utils.py
└── requirements.txt
```

# pipで取得可能なライブラリを使用する場合
一方、pipで取得するようなライブラリは以下のように**vendor**ディレクトリに突っ込みます。

```:shell
$ tree -a
.
├── .chalice
│   └── config.json
├── .gitignore
├── app.py
├── chalicelib
│   ├── __init__.py
│   └── utils.py
├── requirements.txt
└── vendor
```

ここで、例えばrequestsを使う場合は、以下のようにします。

```:shell
$ cd vendor
$ pip download requests
$ cd ..
$ tree -a
.
├── .chalice
│   └── config.json
├── .gitignore
├── app.py
├── chalicelib
│   ├── __init__.py
│   └── utils.py
├── requirements.txt
└── vendor
    ├── certifi-2017.11.5-py2.py3-none-any.whl
    ├── chardet-3.0.4-py2.py3-none-any.whl
    ├── idna-2.6-py2.py3-none-any.whl
    ├── requests-2.18.4-py2.py3-none-any.whl
    └── urllib3-1.22-py2.py3-none-any.whl
```

このようにwhlで落ちてくれば、そのまま利用できますが、
tar.gzでDLされてくるものもあると思います。
たとえばslackwebなんかは

```:shell
$ pip download slackweb
$ cd ..
$ tree -a
.
├── .chalice
│   └── config.json
├── .gitignore
├── app.py
├── chalicelib
│   ├── __init__.py
│   └── utils.py
├── requirements.txt
└── vendor
    └── slackweb-1.0.5.tar.gz
```
こんな感じでDLされます。
[ここ](https://qiita.com/Yutako/items/5437a7f364748f808a50)でも書いていますが
このままデプロイしてもエラーになってしまうため、whl形式への変換が必要です。

```:shell
$ pip wheel slackweb-1.0.5.tar.gz 
$ rm slackweb-1.0.5.tar.gz && cd ..
$ tree -a
.
├── .chalice
│   └── config.json
├── .gitignore
├── app.py
├── chalicelib
│   ├── __init__.py
│   ├── backlog.py
│   ├── backlog_api.py
│   └── utils.py
├── requirements.txt
└── vendor
    └── slackweb-1.0.5-py3-none-any.whl
```

# LambdaのIAM権限
Dynamoやら、他のリソースにアクセスするためには
Lambdaに付与するIAM ROLE権限を修正する必要があります。
`.chalice` 配下に、policy-dev.jsonがありますが、これがLambdaに付与される権限です。


```:shell
$ tree -a
.
├── .chalice
│   ├── config.json
│   ├── deployed.json
│   ├── deployments
│   │   └── 30371575b45c60a8b9201f9999e41202-python3.6.zip
│   └── policy-dev.json
├── .gitignore
├── __pycache__
│   └── app.cpython-36.pyc
├── app.py
├── chalicelib
│   ├── __init__.py
│   ├── backlog.py
│   ├── backlog_api.py
│   └── utils.py
├── requirements.txt
└── vendor
    ├── slackweb-1.0.5-py3-none-any.whl
    └── slackweb-1.0.5.tar.gz
```



# debugする
ローカルで動かすこともできます。
以下のコマンドで、ポート8000で待ち受けてくれます。
Dynamo localや、SAM Localでローカル環境を構築すれば、ローカルでも色々テストができそうです。

```:shell
$ chalice local
Serving on localhost:8000
```

```:shell
$ curl http://localhost:8000/
{"hello": "world"}
```

# deployする
以下のコマンドで、AWS環境にデプロイでいます。
そしてそのままAPIが払い出される！素敵すぎです。

```:shell
$ chalice deploy
Creating role: qiita-advent-dev
Creating deployment package.
Creating lambda function: qiita-advent-dev
Initiating first time deployment.
Deploying to API Gateway stage: api
https://xxxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/api/

```

以上となります！

ぜひ、LambdaとAPI gatewayでサーバーレスなアプリを作ってみてください！