• トップ
  • ブログ一覧
  • 【最終回】FastAPIチュートリアル: toDoアプリを作ってみよう【WebAPI編】
  • 【最終回】FastAPIチュートリアル: toDoアプリを作ってみよう【WebAPI編】

    広告メディア事業部広告メディア事業部
    2020.01.07

    IT技術

    FastAPIチュートリアル: toDoアプリを作ってみよう~最終回~

    前回の記事「【第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 」と「そのコントローラ」がずらっと確認できます。

    toDoアプリのドキュメントが自動生成される

    その中から今作成した、「get」を探しましょう。

    そして、「Try out」から「Execute」をすると、

    JSON形式のタスクを取得できる
    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 を忘れずに!

    動作確認

    先ほどと同じように、ドキュメントを見てみましょう!

    フォームをドキュメントから指定できるようになった

    このようにドキュメントに必要なデータフォームが表示されるようになりました。

    では、実際に動かしてみましょう!

    POSTメソッドがしっかり動作していそうです!
    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 にアクセスするだけです。

    ReDocの確認

    このように静的なドキュメントが自動生成されます。

    やはり、FastAPIは、「API 作成に強い API 」ということが分かりますね。

    さいごに

    これにて、「FastAPIチュートリアル: toDoアプリを作ってみよう」の連載は終了です!

    本連載を通して、FastAPI の使い方や、Webアプリケーションの作り方を理解できたかと思います。

    FastAPI は、まだ発展途上のライブラリですので、これからのアップデートに期待できそうです。

    それでは、第7回にわたりご愛読していただきありがとうございました!

    Responderはオススメ

    他にも、Responder など様々なWebライブラリがありますので、ぜひ他のものも触れてみてください!

    特に、Responderはオススメです!

    featureImg2019.10.25【まとめ編】Responderを使ってDjangoチュートリアルをやってみたResponderを使ってDjangoチュートリアルをやってみた~まとめ~ライトコード社長も今、イチオシのWEBフレー...

    本連載で作成したコード

    本連載で作成したコードは、Githubにアップロードしてありますので、ご自由にお使い下さい!

    https://github.com/rightcode/FastAPITutrial

    広告メディア事業部

    広告メディア事業部

    おすすめ記事