前回に引き続きFlaskにいろいろ実装をしてみます。今回作成するアプリケーションはJavascript側でUIを描画していくため、サーバサイドではデータのやり取りのための最低限の実装をしたいと思います。
REST-APIの実装
まずREST(Representational state transfer)ful APIについてですが、実際にどのようなものかは、チュートリアルサイトのようなものもありますので、そちらを参照いただければと思います。
簡単に言えばHTTPプロトコルの各種メソッド(GET/PUT/POST/DELETE)とJSON形式のデータをもとに、サーバクライアント間でデータのやり取りを行うAPIになります。
例えば、下記のような感じです。curlコマンドにてPOSTメソッドを用いてhogeの中のid=1のデータを取ってくるイメージです。
$ curl -X GET http://example.com/api/v1/hoge/id/1
{
meta: {
},
hoge: {
id: 1,
data: 'fuga',
}
}
このようにクライアント側のJavascriptとサーバ側がデータのみをやり取りし、クライアント側の描画を動的に更新することにより、あたかもアプリケーションライクな動作を行うことができます。このようなAPIは他にもありますが、有名どころではSOAP(Simple Object Access Protocol)がよく比較として挙げられます。
早速Flaskで実装してみましょう。(いくつかflask専用のライブラリが出ているようですが、勉強のためにそのまま実装します。)
前回実装したapp.pyに追記してみます。
from flask import Flask, render_template, request # requestを追加
app = Flask("__name__")
database = []
@app.route("/")
def root():
return render_template("index.html")
# 今回の実装箇所 ----
@app.route("/api/v1/<string:userId>", methods=['GET','POST','PUT','DELETE'])
def api_get(userId):
# GETの場合はuserIDにマッチするデータをデータベースから取得しJSON形式でデータを返却
if request.method == 'GET':
for i in xrange(len(database)):
if database[i]['id'] == userId:
return '{"data" : "%s"}' %(database[i]['data'])
return '{"result" : "error"}'
# POST/PUTは送信されたJSON形式のデータを受け取り、データベースに格納
elif request.method in ['POST','PUT']:
query_json = request.get_json()
data = {}
if (query_json.has_key('data')):
data['id'] = userId
data['data'] = query_json['data']
database.append(data)
return '{"result" : "success"}'
else:
return '{"result" : "error"}'
# DELETEは送信されたJSON形式のデータを受け取り、データベースから削除
elif request.method == 'DELETE':
for i in xrange(len(database)):
if database[i]['id'] == userId:
del(database[i])
return '{"result" : "success"}'
return '{"result" : "error"}'
return '{"result" : "error"}'
# ---
if __name__ == "__main__":
app.run(debug=True)
実際にサーバを起動し、curlコマンドで動作を確認してみます。
# サーバ側
$ python app.py runserver
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
127.0.0.1 - - [01/Sep/2018 00:10:38] "POST /api/v1/1 HTTP/1.1" 200 -
127.0.0.1 - - [01/Sep/2018 00:10:49] "POST /api/v1/2 HTTP/1.1" 200 -
127.0.0.1 - - [01/Sep/2018 00:10:53] "GET /api/v1/2 HTTP/1.1" 200 -
127.0.0.1 - - [01/Sep/2018 00:11:06] "DELETE /api/v1/2 HTTP/1.1" 200 -
127.0.0.1 - - [01/Sep/2018 00:11:19] "GET /api/v1/2 HTTP/1.1" 200 -
curlでJSONを送付する際には、データがJSON形式だとわかるように-H "Content-Type: application/json"を付与して送付する必要があります。(app.pyのrequest.get_json()はContent-Type: application/jsonをもとにJSON形式を判定しているため、ヘッダをつけない場合、データが格納されません。)
# クライアント側
$ curl -X POST http://127.0.0.1:5000/api/v1/1 -d '{"data":"hoge"}' -H "Content-Type: application/json"
{"result" : "success"}
$ curl -X POST http://127.0.0.1:5000/api/v1/2 -d '{"data":"hoge2"}' -H "Content-Type: application/json"
{"result" : "success"}
$ curl -X GET http://127.0.0.1:5000/api/v1/2
{"data" : "hoge2"}
$ curl -X DELETE http://127.0.0.1:5000/api/v1/2
{"result" : "success"}
$ curl -X GET http://127.0.0.1:5000/api/v1/2
{"result" : "error"}
次回もFlaskの機能を使った実装を進めていきたいと思います。