GAE(python)のRESTfulなAPIのフレームワークのrest_gae
budowski/rest_gae · GitHubというGoogle App Engine上で動くpythonのRESTfulなWeb APIのフレームワークを使っているが、とても便利。
日本語での参考サイトがないので、メモとしてまとめる。
[概要]
Web APIなんて結局、jsonリクエストを受け取って、パラメータチェックして、レスポンスをjsonで返すだけのもの。
そのほとんどの機能をrest_gaeは提供する。インタフェースはREST。
1. ユーザ管理API
ユーザ作成、変更、削除などをのAPIがある。
1-1. 独自ユーザクラスの定義
from rest_gae.users import User class MyUser(User): """Our own user class""" prop1 = ndb.StringProperty(required=True) prop2 = ndb.StringProperty()
独自のユーザ情報(この場合は、prop1とprop2)が必要なければ、デフォルトで提供されているUserクラスを使えば良い。
Userクラスが持っているプロパティは、
・ユーザ名
・パスワード(ハッシュ化)
・adminユーザかどうか
・email認証済みかどうか
・作成日時と変更日時
※ドキュメントには書いてなかったので、ソースコードと実際に追加されたDataStoreから解析した!
そして、これを動かすには下記を記述する。
from rest_gae import * # This imports RESTHandler and the PERMISSION_ constants from rest_gae.users import UserRESTHandler # Make sure we initialize our WSGIApplication with this config (used for initializing webapp2_extras.sessions) config = {} config['webapp2_extras.sessions'] = { 'secret_key': 'my-super-secret-key', } app = webapp2.WSGIApplication([ UserRESTHandler( '/api/users', # The base URL for the user management endpoints user_model='models.MyUser', # Use our own custom User class user_details_permission=PERMISSION_LOGGED_IN_USER, verify_email_address=True, verification_email={ 'sender': 'John Doe <john@doe.com>', 'subject': 'Verify your email', 'body_text': 'Hello {{ user.full_name }}, click here: {{ verification_url }}', 'body_html': 'Hello {{ user.full_name }}, click <a href="{{ verification_url }}">here</a>' }, verification_successful_url='/verified-user', verification_failed_url='/verification-failed', reset_password_url='/reset-password', reset_password_email={ 'sender': 'John Doe <john@doe.com>', 'subject': 'Reset your password', 'body_text': 'Hello {{ user.name }}, click here: {{ verification_url }}', 'body_html': 'Hello {{ user.name }}, click <a href="{{ verification_url }}">here</a>' }, send_email_callback=my_send_email, allow_login_for_non_verified_email=False, user_policy_callback=lambda user, data: if len(data['password']) < 8: raise ValueError('Password too short') )], config=config)
UserRESTHandlerの中を見ていく。
'/api/users', # The base URL for the user management endpoints
URLを定義する。この場合、
http://ホスト名/api/users
でユーザ管理APIにアクセスすることになる。
user_model='models.MyUser', # Use our own custom User class
ユーザモデルの定義。先ほど作ったMyUserを使う。
user_details_permission=PERMISSION_LOGGED_IN_USER,
ユーザ情報を取得できるユーザの権限を設定している。ここでは、PERMISSION_LOGGED_IN_USERという(そのアカウントで)ログインしたユーザ以上に権限がある。
ユーザの権限には、下記がある。下に行くに従い、権限が強くなる。
・PERMISSION_ANYONE
・PERMISSION_LOGGED_IN_USER
・PERMISSION_OWNER_USER
・PERMISSION_ADMIN
その他の部分は、メール認証に関する機能で今回は無視する。
1-2. ユーザ管理APIの呼び出し
【実行サンプルあり】
A) POST /users : ユーザ情報の登録。誰でも可。
B) POST /users/login : ログイン。誰でも可。
C) GET /users/エンティティキー : あるユーザ情報の取得。前述の通りログインユーザ以上で可。
【実行サンプルなし】
GET /users : 全ユーザ情報の取得。adminユーザのみ可。
PUT /users/エンティティキー : ユーザ情報変更。パスワードも変更できる。ログインユーザ以上で可。
DELETE /users/エンティティキー : ユーザ情報削除。ログインユーザ以上で可。
【実行サンプルあり】のAPIを実際に呼び出してみる。
A) POST /users : ユーザ情報の登録。誰でも可。
email, user_name, passwordがUserクラスの必須のパラメータ。MyUserクラスでprop1を必須で定義したので、prop1も必須。
レスポンスでエンティティキーがidという名で返ってくる。
DataStore Viewerで中身をチェックすると、
ちゃんと値が入っている。
B) POST /users/login : ログイン。誰でも可。
れクエストはuser_nameとパスワードが必須。
レスポンスではuser_idが返される。これはMyUserエンティティのIDに一致する。つまり、ログインではMyUserエンティティキーは返却されない。
これがC) GET /users/エンティティキーの呼び出しで問題になる。エンティティキーがログインで取得できないので、下の2つのどちらかで対応する必要がある。
ア)アカウント作成時にローカルに保存(スマホアプリのみ可)
イ)エンティティキーを取得するAPIを別途用意する。
イ)の場合のサーバ側での処理は、
1.IDをクライアントから受け取る
2.ndb.Key(MyUser, IDの値).urlsafe()でエンティティキーを取得(※これがわからず苦労した)。
(例)ndb.Key(MyUser,4677872220372992).urlsafe()
3.クライアントに返却
ア)、イ)以外にもっと良いやり方があるかもしれないが、わからなかったのでこれで進めている。(誰か知っていたら教えて下さい。 )
※2015/4/18 追記
※ /users/me で自分のアカウントにアクセスできる(と分かった)ので、エンティティキーの取得は不要だった。
C) GET /users/エンティティキー : あるユーザ情報の取得。前述の通りログインユーザ以上で可。
取得成功。
Modelを追加してAPIを呼び出しもだいたい同じ感じ。次回書く。