【最終回】FastAPIチュートリアル: toDoアプリを作ってみよう【WebAPI編】
IT技術
前回の記事「【第6回】FastAPIチュートリアル: toDoアプリを作ってみよう【予定の追加・削除編】」の続きです。
今回も、toDo アプリを作る過程で、FastAPI の使い方を学んでいきましょう!
第1回はこちら
「WebAPI」化を目指します!
こちらの連載は、今回の第7回をもって「最終回」となります。
最終回では、FastAPI の本命と言っても良い「WebAPI」化を目指します。
第1回でも言ったように、FastAPI は「対ユーザ」のアプリケーションは実は不向きで、本命は「対プログラム」の WebAPI を作成するためのライブラリです。
つまり、本連載で作成する toDoアプリケーションは、GUI・CUI ( CLI ) 両方で機能する toDoアプリにしていきます。
前者はもう実装終わりましたので、最終回は後者を実装していきたいと思います!
ログインユーザのタスクを全てJSON形式で取得する
まずは、最も単純な API です。
API はそもそも、他のプログラムから呼び出されることが前提ですので、扱いやすい形でレスポンスする必要があります。
よく扱われるのは、JSON (JavaScript Object Notation) 形式です。
ルーティング
ルーティングは、ずっとやってきたことと同じです。
1# FastAPIのルーティング用関数
2app.add_api_route('/', index)
3app.add_api_route('/admin', admin, methods=['GET', 'POST'])
4app.add_api_route('/register', register, methods=['GET', 'POST'])
5app.add_api_route('/todo/{username}/{year}/{month}/{day}', detail)
6app.add_api_route('/done', done, methods=['POST'])
7app.add_api_route('/add', add, methods=['POST'])
8app.add_api_route('/delete/{t_id}', delete)
9
10# JSONで返すAPI
11app.add_api_route('/get', get) # new
コントローラを書く
こちらも、さほど難しくはないと思います。
やることは、GUIでやってきたこととほとんど同じで、return の仕方が異なるだけです。
1def get(request: Request, credentials: HTTPBasicCredentials = Depends(security)):
2 # 認証
3 username = auth(credentials)
4
5 # ユーザ情報を取得
6 user = db.session.query(User).filter(User.username == username).first()
7
8 # タスクを取得
9 task = db.session.query(Task).filter(Task.user_id == user.id).all()
10
11 db.session.close()
12
13 # JSONフォーマット
14 task = [{
15 'id': t.id,
16 'content': t.content,
17 'deadline': t.deadline.strftime('%Y-%m-%d %H:%M:%S'),
18 'published': t.date.strftime('%Y-%m-%d %H:%M:%S'),
19 'done': t.done,
20 } for t in task]
21
22 return task
実際に確認してみる
FastAPIでは、APIのレスポンスを確認するのは簡単です。
これが、FastAPI の最大のメリットかもしれません。
サーバを立ち上げたら、http://127.0.0.1:8000/docs にアクセスしましょう。
すると「今まで書いてきた URL 」と「そのコントローラ」がずらっと確認できます。
その中から今作成した、「get」を探しましょう。
そして、「Try out」から「Execute」をすると、
1[
2 {
3 "id": 1,
4 "content": "〇〇の締め切り",
5 "deadline": "2019-12-25 12:00:00",
6 "published": "2019-10-08 17:43:31",
7 "done": false
8 },
9 {
10 "id": 2,
11 "content": "太郎とランチ",
12 "deadline": "2019-10-21 12:00:00",
13 "published": "2019-10-19 22:17:18",
14 "done": true
15 },
16 {
17 "id": 3,
18 "content": "□□□へ振り込み",
19 "deadline": "2019-11-01 16:00:00",
20 "published": "2019-10-21 17:12:06",
21 "done": false
22 }
23]
うまく動作していそうですね。
実際は、ベーシック認証を挟むので、コンソールから取得する場合は
1$ curl -u username:password http://127.0.0.1:8000/get
のようにユーザ名とパスワードが必要です。
ちなみに、引数のrequest: Request はなくても良いです。
POSTメソッドを伴うAPI
次に、コマンドラインからタスクを追加し、新しく追加したタスクをJSONで返すようなAPIを作成します。
ここでは、POSTメソッドとしてデータが送信された時を考えます。
したがって、ルーティングは以下のようになります。(関数名は適当に決めます)
1# JSONで返すAPI
2app.add_api_route('/get', get)
3app.add_api_route('/add_task', insert, methods=['POST']) # new
コントローラを書く
コントローラを書いていきますが、GUI と同じような POST メソッドの受け取りかたは使わず、ドキュメントに反映されるように FastAPI のForm() 関数を使います。
まずは、新たにインポートしてください。
1from fastapi import FastAPI, Depends, Form
Form()を使ったPOSTメソッドの受け取りかたは、以下のように書きます。
1async def insert(request: Request,
2 content: str = Form(...), deadline: str = Form(...),
3 credentials: HTTPBasicCredentials = Depends(security)):
4 """
5 タスクを追加してJSONで新規タスクを返す。「deadline」は%Y-%m-%d_%H:%M:%S (e.g. 2019-11-03_12:30:00)の形式
6 """
7 # 認証
8 username = auth(credentials)
9
10 # ユーザ情報を取得
11 user = db.session.query(User).filter(User.username == username).first()
12
13 # タスクを追加
14 task = Task(user.id, content, datetime.strptime(deadline, '%Y-%m-%d_%H:%M:%S'))
15
16 db.session.add(task)
17 db.session.commit()
18
19 # テーブルから新しく追加したタスクを取得する
20 task = db.session.query(Task).all()[-1]
21 db.session.close()
22
23 # 新規タスクをJSONで返す
24 return {
25 'id': task.id,
26 'content': task.content,
27 'deadline': task.deadline.strftime('%Y-%m-%d %H:%M:%S'),
28 'published': task.date.strftime('%Y-%m-%d %H:%M:%S'),
29 'done': task.done,
30 }
POSTメソッドを受け取るときは、async を忘れずに!
動作確認
先ほどと同じように、ドキュメントを見てみましょう!
このようにドキュメントに必要なデータフォームが表示されるようになりました。
では、実際に動かしてみましょう!
1{
2 "id": 6,
3 "content": "Hogehoge",
4 "deadline": "2019-12-24 12:00:00",
5 "published": "2019-10-21 19:10:16",
6 "done": false
7}
うまく動作していそうです!
これで外部からタスクの追加ができるようになり、WebAPIとして動作するようになりました。
他にも、API化すべき機能がありますが、どれも同じような解説になるので、ここまでにしておきたいと思います!
ReDocの確認
最後に、FastAPI で自動生成される ReDoc について確認の仕方を解説して連載を終わりにしたいと思います。
といっても簡単で、http://127.0.0.1:8000/redoc にアクセスするだけです。
このように静的なドキュメントが自動生成されます。
やはり、FastAPIは、「API 作成に強い API 」ということが分かりますね。
さいごに
これにて、「FastAPIチュートリアル: toDoアプリを作ってみよう」の連載は終了です!
本連載を通して、FastAPI の使い方や、Webアプリケーションの作り方を理解できたかと思います。
FastAPI は、まだ発展途上のライブラリですので、これからのアップデートに期待できそうです。
それでは、第7回にわたりご愛読していただきありがとうございました!
Responderはオススメ
他にも、Responder など様々なWebライブラリがありますので、ぜひ他のものも触れてみてください!
特に、Responderはオススメです!
本連載で作成したコード
本連載で作成したコードは、Githubにアップロードしてありますので、ご自由にお使い下さい!
https://github.com/rightcode/FastAPITutrial
ResponderとFastAPIを実際に使って比較してみた
こちらの記事もオススメ!
2020.07.17ライトコード的「やってみた!」シリーズ「やってみた!」を集めました!(株)ライトコードが今まで作ってきた「やってみた!」記事を集めてみました!※作成日が新し...
2020.07.30Python 特集実装編※最新記事順Responder + Firestore でモダンかつサーバーレスなブログシステムを作ってみた!P...
ライトコードでは、エンジニアを積極採用中!
ライトコードでは、エンジニアを積極採用しています!社長と一杯しながらお話しする機会もご用意しております。そのほかカジュアル面談等もございますので、くわしくは採用情報をご確認ください。
採用情報へ
「好きを仕事にするエンジニア集団」の(株)ライトコードです! ライトコードは、福岡、東京、大阪の3拠点で事業展開するIT企業です。 現在は、国内を代表する大手IT企業を取引先にもち、ITシステムの受託事業が中心。 いずれも直取引で、月間PV数1億を超えるWebサービスのシステム開発・運営、インフラの構築・運用に携わっています。 システム開発依頼・お見積もり大歓迎! また、現在「WEBエンジニア」「モバイルエンジニア」「営業」「WEBデザイナー」「WEBディレクター」を積極採用中です! インターンや新卒採用も行っております。 以下よりご応募をお待ちしております! https://rightcode.co.jp/recruit