TwitterAPIをServerlessを使ってLambda + Pythonで動かしてAPIGatewayで呼び出せるようにしてみた

# 前提
Node.jsで動かしてみてしっくりこなかったのでPython3でTwitterAPIを動かして見たいと思います。

Node.jsの記事
https://qiita.com/tama0571046/items/2bd9c94bbe3474243bea

2023/03/03追記
TwitterAPIが有料化したため利用が難しくなりましたが、サーバーレス自体は利用できると思いますので参考にしてください。

# dockerのインストール
後述する**serverless-python-requirements**で必要になります
こちらのサイトからインストールできます
https://www.docker.com/


# AWSクレデンシャルの設定

アクセスキーとシークレットキーはAWSのユーザから取得してください

```zsh
aws configure
> aws_access_key_id: ***
> aws_secret_access_key: ***
> region: ap-northeast-1
> output: json
```

# serverlessとプラグインのインストール
```zsh
npm install -g serverless
npm install --save serverless-python-requirements
npm install --save serverless-dotenv-plugin
npm install --save serverless-offline
```


# プロジェクトを作成
```zsh
sls create -t aws-python3 -p twitter_server_python3
cd twitter_server_python3
```

# serverless.ymlを修正
```yaml:twitter_server_python3/serverless.yml
service: twitter-server-python3

custom:
  dotenv:
    basePath: ./
  stage: ${env:STAGE}
  region: ${env:REGION}
  pythonRequirements:
    dockerizePip: true

provider:
  name: aws
  runtime: python3.7
  stage: ${self:custom.stage}
  region: ${self:custom.region}
  apiName: ${self:service}-${self:provider.stage}

plugins:
  - serverless-python-requirements
  - serverless-dotenv-plugin
  - serverless-offline

functions:
  hello:
    handler: handler.hello
    name: ${self:service}-hello-${self:provider.stage}
    events:
      - http:
          path: /hello
          method: get
          integration: lambda
  get_follow:
    handler: handler.get_follow
    name: ${self:service}-get_follow-${self:provider.stage}
    events:
      - http:
          path: /get_follow
          method: get
          integration: lambda
  get_list:
    handler: handler.get_list
    name: ${self:service}-get_list-${self:provider.stage}
    events:
      - http:
          path: /get_list
          method: get
          integration: lambda
```

# .envファイルを追加
プロジェクト直下に**.env**ファイルを作成

```zsh
vim .env
```

```vim:twitter_server_python3/.env
STAGE=dev
REGION=ap-northeast-1

CONSUMER_KEY=***
CONSUMER_SECRET=***
ACCESS_TOKEN=***
ACCESS_TOKEN_SECRET=***
```

# requirements.txtを追加
プロジェクト直下に**requirements.txt**ファイルを作成

```zsh
vim requirements.txt
```

```vim:twitter_server_python3/requirements.txt
tweepy==3.8.0
```

# ローカル環境での実行

仮想環境を作成して仮想環境内に入る

```zsh
python3.7 -m venv .venv
source .venv/bin/activate
```

仮想環境内でモジュールをインストール

```zsh:.venv
pip install -r requirements.txt
``` 

ローカル環境で実行

```zsh:.venv
sls invoke local --function hello
```

仮想環境から出る

```zsh
deactivate
```


# Lambda
### デプロイ
```zsh
sls deploy -v
```

### 実行
```zsh
sls invoke -f hello --log
```

### デプロイした内容を削除
```zsh
sls remove
```

# API Gateway
AWSにログインして**Lambda**の今回作成した関数を開く
デザイナーにAPIGatewayがあるはずなので、開くと**API エンドポイント**からURLが確認できます

```zsh
curl https://*****.execute-api.ap-northeast-1.amazonaws.com/dev/get_follow
```

# POSTがaxiosからうまく行かない
### APIGateway
アクションから**CORSの有効化**をクリック

POSTメソッドから統合リクエストをクリック
マッピングテンプレートを**テンプレートが定義されていない場合(推奨)**をクリック
application/jsonのリンクをクリックしてテンプレートの生成を**メソッドリクエストのパススルー**を選択して保存

### axios
pulugin/axios.jsを追加して下記を記述

```js:plugin/axios.js
export default ({ $axios }) => {
  $axios.defaults.headers.common = {}
}
```

nuxt.config.jsに追記

```js:nuxt.config.js
plugins: [
  ...
  "@/plugins/axios"
],
```

index.vueでaxiosを読み込み
bodyをJSON.stringfyにするのを忘れない

```vue:index.vue
import axios from 'axios'

export default {
  components: { axios },
  ...
  methods: {
    async onSave() {
      await axios.post(postListMembersURL, JSON.stringify({}))
    }
  }
```

### ブラウザ
CORSの設定を追加