responderで理解するWebサーバー #1

こんにちは。Webエンジニアのjuri-tです。

最近軽く触ってみたresponderというフレームワークが割と良かったので、普及活動のために記事にしたいと思います。

タイトルは入門ですが、入門したのは私です。

断っておきたいこととしては、割と良かったというのは私個人の感想なので、PythonのWeb Application Framework(以下WAF)としてresponderを選択すべきと主張するわけではありません。

1. responderとは

Githubのリポジトリから引用すると、以下で説明されています。

A familiar HTTP Service Framework for Python.

HTTP Service Frameworkは、PythonでメジャーどころだとDjangoFlaskあたりがよく使われているかと思います。Djangoが2005年、Flaskが2010年に対し、responderは2018年なのでかなり最近のフレームワークとなっています。

特徴としてはいくつかありますが、DjangoやFlaskとの違いは非同期である点が大きいかと思います。非同期であるがゆえに、非同期な処理を書くのが非常に簡単です。(他の特徴についてはGithubに書いてますし、すでにresponderを試した方々がまとめてくれているので割愛します)

同じくPythonの非同期なWAFとして、最近fastapiが出ましたが、少し使ってみた感想はresponderのほうが私の好みでした。ここでちょっとresponderの例を見てみましょう。

import responder

api = responder.API()

@api.route("/{greeting}")
async def greet_world(req, resp, *, greeting):
    resp.text = f"{greeting}, world!"

if __name__ == '__main__':
    api.run()

これは、Githubにも載っている簡単なサンプルです。私がFlaskやfastapiより良いと思った点はここにあります。

Flaskに載っているサンプルは以下のようになります。responderはFlaskやFalconにインスパイヤされているので、かなり似てますね。

from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello_world():
   return "Hello World!"

if __name__ == '__main__':
   app.run()

responderでは、リクエストオブジェクト、レスポンスオブジェクトともに引数で明示されていますが、Flaskでは明示されていません。Flaskでrequestを使うにはflaskモジュールからimportする必要があります。レスポンスオブジェクトなども同様です。

また、responderの場合は単一のimport文でほとんどすべての機能が使えます。Flaskではテンプレートエンジンを使うときは、render_templateを追加でimportする必要がありますが、responderではAPIインスタンスがtemplateメソッドを持っています。(jinja2が使えます)

明示的でスッキリと書くのが好きな方はresponderおすすめです。

fastapiも見てみましょう。

from fastapi import FastAPI
app = FastAPI()

@app.get("/")
def read_root():
   return {"Hello": "World"}

@app.get("/items/{item_id}")
def read_item(item_id: int, q: str = None):
   return {"item_id": item_id, "q": q}

ルーティングはFlask、responderに近いですが、基本的に返すものはjsonです。おそらくAPIサーバーとしてのユースケースをメインで想定していそうです。(もちろん静的ファイルも返せますが、これよりはごちゃごちゃとしないといけないです)

fastapiではtype hintの型付けによるバリデーションとかが可能になるんですが、正直Pythonの型はそこまで便利とは言い難い上、良くも悪くもオプションを書くとFramework側がうまくやってくれる感じで個人的にはちょっと使いづらいなという印象でした。

というわけでresponderおすすめです(2回目)

ただし、まだ発展途上なのでsessionのストア先がcookieしかなかったりします。秘匿情報をsessionに持たせたい場合、あまりcookieに持たせたくありません。その場合は自前でやる必要があります。

サーバーサイドセッションに関するissue

他にもまだ落とし穴があるかもしれません。というわけで、今後は実戦として使えるのかをいろいろ試していきたいと思っています。

追記 2019.7.11

responderのsessionは暗号化はされていませんでした。該当の記述を削除しました。


サポートありがとうございます。頂いたご支援は美味しいものを食べに行きます。