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

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

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

    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

    ライトコードでは、エンジニアを積極採用中!

    ライトコードでは、エンジニアを積極採用しています!社長と一杯しながらお話しする機会もご用意しております。そのほかカジュアル面談等もございますので、くわしくは採用情報をご確認ください。

    採用情報へ

    広告メディア事業部
    広告メディア事業部
    Show more...

    おすすめ記事

    エンジニア大募集中!

    ライトコードでは、エンジニアを積極採用中です。

    特に、WEBエンジニアとモバイルエンジニアは是非ご応募お待ちしております!

    また、フリーランスエンジニア様も大募集中です。

    background