プロジェクトとアプリの構成

何がスマートなのかは人それぞれ、プロジェクト事に違うと思いますが。
最近色々触ってみて、気付いた点。WSGI の話しです。

Werkzeug の Routing System はシンプルながら強力です。

Django で不満だった正規表現や階層の問題をシンプルに解決してくれています。

さらに WSGI で、アプリケーション事にキレイに URI を分けられるため、
何がスマートな解決方法なのかを模索しています。

色々省略してますが二つパターンを考えてみました。

パターン A

  • ここのアプリケーションに urls.py を持たせて main.py でそれぞれの app.py を纏める方法
  • tests.py が独立できます
  • werkzeug のテストは application を渡せば client.get('/') とか簡単に GAE 上でもテストできます。
- /project
  - main.py
  - utils.py
  - /core
    - app.py
    - models.py
    - views.py
    - forms.py
    - urls.py
    - tests.py
  - /api
    - app.py
    - models.py
    - views.py
    - urls.py
    - tests.py
  - /admin
    - app.py
    - models.py
    - views.py
    - forms.py
    - urls.py
    - tests.py
  - /werkzeug
  - /jinja2
  - /dateutil

パターン B

  • urls.py で全てをまとめ上げてしまう方法
  • urls.py が集約されシンプルでわかりやすくなります。
  • とにかくシンプルになります。tests.py もまとめられます。
    • 逆に言えばキレイに書くには纏めなければ行けません。
- /project
  - main.py
  - utils.py
  - urls.py
  - tests.py
  - /core
    - models.py
    - views.py
    - forms.py
  - /api
    - models.py
    - views.py
  - /admin
    - models.py
    - views.py
    - forms.py
  - /werkzeug
  - /jinja2
  - /dateutil

パターン C .. 妄想

これを目指したい気はする。でも contrib.admin などなどが必要:-P
ほとんど Django っぽくなるけどこれが一番スマート?

- /project
  - main.py
  - utils.py
  - /app1
    - app.py
    - urls.py
    - models.py
    - views.py
    - forms.py
    - api.py
    - admin.py
    - tests.py
  - /app2
    - app.py
    - urls.py
    - models.py
    - views.py
    - forms.py
    - api.py
    - admin.py
    - tests.py
  - /werkzeug
  - /jinja2
  - /dateutil

悩む

今は A を採用していますが、もしかして B のほうがとてもシンプルでいいのかなぁと。
A はなんとなく Django っぽいです。B は Werkzeug っぽいです Zine がこの方式を採用しています。
B の場合は urls.py がシンプルです、EndpointPrefix と Submount を使ってキレイに書けます。

url_map = Map([
  EndpointPrefix('core/', [
    Rule('/', endpoint='index'),
    Rule('/entry/<string:entry_slug>', endpoint='show')
  ])
  EndpointPrefix('api/', [
    Submount('/api', [
      Rule('/', endpoint='index'),
      Rule('/entry/<string:entry_slug>', endpoint='show')
    ])
  ])
  EndpointPrefix('admin/', [
    Submount('/admin', [
      Rule('/', endpoint='index'),
      Rule('/entry/<string:entry_slug>', endpoint='show')
    ])
  ])
])

結論

とりあえず A で書いてみて面倒だったら B へ移行するという事で自分を納得させています。

他にも色々有ると思います。GAE の webapps は app.yaml によって呼び出される *.py を変更できるのでそれでハンドリングするのもありだとおもいます。

とにかく、構築が楽でで理解しやすくて、読みやすいものを模索中です。

project == applicaiton という錯覚を最近起こしている気はします。Django のようにキレイに抽象化出来たらいいのですが .. :-(