GCPのGAEでDataStoreにデータ投入して検索するAPIのサンプル作ってみた

前回の続き、GCPの開発環境は作ってみたものの。肝心のGAE+DataStoreの環境ができていないのでローカル環境でサンプル的なものを作って動かしてみることにした。
もしかしたらDynamoDBでも似た様な事をできるのかもしれないけどグローバルセカンダリインデックスの考え方がよく分からなかったのと複合条件とかが結構複雑な考え方でやらないといけないっぽかったのでGCPとAWSを適材に応じて使えますとか言ったら、転職に有利になるかと、会社のお役に立てると思い今回はGAEでやってみました。

1.環境構築
(1)作業用ディレクトリ作成
$ mkdir flasksample
$ cd flasksample

(2)DataStore用cloud-gui導入
参考サイト:
https://engineer.crowdworks.jp/entry/2019/03/08/161559 https://qiita.com/kerupani129/items/60ee8c8becc2fe9f0d28

$ mkdir datastore
$ cd datastore
$ cd ../
$ sudo apt update
$ sudo apt install -y nodejs npm
$ curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
$ echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
$ sudo apt update
$ sudo apt -y install yarn
$ sudo yarn global add google-cloud-gui
$ sudo npm i -g google-cloud-gui

(3)CloudSDK設定 参考サイト:
https://qiita.com/G-awa/items/e6904b040caa0096fba0 https://qiita.com/sky0621/items/597d4de7ed9ba7e31f6d https://cloud.google.com/docs/authentication/getting-started?hl=ja

#初期設定
$ gcloud init
You must log in to continue. Would you like to log in (Y/n)?  Y
Go to the following link in your browser:
~略~
Enter verification code: 
You are logged in as: [].
~略~
Pick cloud project to use:
~略~
* Run `gcloud topic --help` to learn about advanced features of the SDK like arg files and output formatting

#認証キーの設定
#コンソールからAPIキーを作成しjsonに保管してサーバにアップロード
$ echo "export GOOGLE_APPLICATION_CREDENTIALS=\"/home/hoge/pjname-a12345.json\"" >> /home/hoge/.bashrc

(4)DataStore用設定
参考サイト:
https://code-library.site/cloud-datastore1/ https://qiita.com/tfuruya/items/fa529c6cf54adaa81aa7

#環境変数に反映
$ echo "export DATASTORE_EMULATOR_HOST=localhost:8081" >> /home/hoge/.bashrc
$ cd 
$ source .bashrc
$ echo $DATASTORE_EMULATOR_HOST
localhost:8081

#外部ライブラリインストール
$ pip3 install google-cloud-datastore
$ pip3 install flask $ pip3 install flask_api $ pip3 install json $ pip3 install jsonify $ pip3 install make_response $ pip3 install request $ pip3 install Response $ pip3 install gunicorn

2.プログラムサンプル
・参考サイト
http://toricor.hatenablog.com/entry/2016/01/16/160406
https://qiita.com/tamago324/items/3b189a87342ae6120b1c
https://qiita.com/naoko_s/items/04d68998cfdbe9c1b5f2
https://qiita.com/naoiwata/items/e9c29386f5a06f58dfc0

---main.py----
# coding: UTF-8
import json
from flask import Flask, jsonify, make_response, request, Response
from flask_api import status
from google.cloud import datastore
import datetime

app = Flask(__name__)
client = datastore.Client()

@app.route('/api/createdata', methods=['POST'])
def create_user():
  try:
    data = request.data.decode('utf-8')
    data = json.loads(str(data))
    key = client.key("Task")
    entity = datastore.Entity(key)
    entity.update(data)
    client.put(entity)
    response = jsonify({'status':'200','message': 'success'})
    return response
  except Exception as e:
    result = error_handler(e)
    return result

@app.route('/api/searchdata', methods=['GET'])
def search_data():
  try:
    data = request.data.decode('utf-8')
    data = json.loads(str(data))
    keylist= [i for i in data.keys()]
    valuelist = [ j for j in data.values()]
    query = client.query(kind="Task2")
    for k,v in zip(keylist,valuelist):
        query.add_filter(k, "=", v )
    result = list(query.fetch())
    return jsonify(result)
  except Exception as e:
    return error_handler(e)

@app.errorhandler(400)
@app.errorhandler(404)
@app.errorhandler(500)
def error_handler(error):
    response = jsonify({
                          "error": {
                          "type": error.name,
                          "message": error.description
                          }
                      })
    return response, error.code

if __name__ == '__main__':
  app.debug=True
  app.run(host='0.0.0.0')


3.実行方法

#DataStoreをローカル環境でスタート(ディレクトリ指定)
$ gcloud beta emulators datastore start --data-dir=datastore

#別ターミナルで実行
$ google-cloud-gui --skip-browser

#さらに別ターミナルで実行
$ cd flasksample
$ python3 main.py

#curlの呼出し方例(上記3つと別のターミナルで実行)
curl http://localhost:5000/api/createdata -X POST -H "Content-Type: application/json" -d '{"key1": "value1","key2": "value2","key3": "value3"}'
curl http://localhost:5000/api/searchdata -X GET -H "Content-Type: application/json" -d '{"key1": "value1"}'

非エンジニアで周囲に相談もできなくて調べながら悩んだものの、できてしまえばあっさりしたものです。Lambdaより外部ライブラリの組込みとかが楽なのと、ローカルで検証するところが割合柔軟にできるので、用途によってはこちらの方がいいかもしれないなぁと思ったりした。
けどLambdaと違ってセキュリティとかエラー箇所については色々と実装に頭を使わないといけないのとある程度、言語に精通していないと厳しいので
お手軽さではAWSのAPIGateway+Lambda+DynamoDBに軍配が上がるかと思います。

後はテストの終わったこのプログラムに追加で以下のファイルを準備して
requirements.txt(同梱するパッケージを指定、デプロイ時にGAEに入れてくれるみたい)
app.yml(動作環境の設定などを書くらしい。)
gcloud app deployコマンドでデプロイしてあげればいいみたいだけど、そこまでは今回はしない。この状態でWeb公開は少し危険なのでもう少し安全性考えてからかなと思った次第、ひとまずセキュリティのお勉強してから再挑戦していきます。今のままだとAPIを直叩きするとDataStoreにレコードが勝手に作られて危険なのでデプロイはしない。

ほんとはバッチでDataStoreにJSONファイルのデータを展開して外部からは参照のAPIしか叩かせないとかしたいんだけどそこまでには至らず。まだまだ、先は長いなぁ。

コメント

このブログの人気の投稿

証券外務員1種勉強(計算式暗記用メモ)

GASでGoogleDriveのサブフォルダとファイル一覧を出力する

マクロ経済学(IS-LM分析)