回答:
RESTful APIを設計する際に注意する必要があるのは、GETとPOSTを同じものであるかのように融合することです。Djangoの関数ベースのビューとCherryPyのデフォルトディスパッチャーでこの間違いを犯すのは簡単ですが、両方のフレームワークがこの問題を回避する方法を提供します(それぞれクラスベースのビューとMethodDispatcher)。
HTTP動詞は RESTで非常に重要であり、これについて十分に注意しない限り、RESTアンチパターンに陥ることになります。
それを正しく行ういくつかのフレームワークは、web.py、Flask、Bottleです。mimerenderライブラリ(完全な開示:私が書いたもの)と組み合わせると、RESTfulなWebサービスを作成できます。
import web
import json
from mimerender import mimerender
render_xml = lambda message: '<message>%s</message>'%message
render_json = lambda **args: json.dumps(args)
render_html = lambda message: '<html><body>%s</body></html>'%message
render_txt = lambda message: message
urls = (
'/(.*)', 'greet'
)
app = web.application(urls, globals())
class greet:
@mimerender(
default = 'html',
html = render_html,
xml = render_xml,
json = render_json,
txt = render_txt
)
def GET(self, name):
if not name:
name = 'world'
return {'message': 'Hello, ' + name + '!'}
if __name__ == "__main__":
app.run()
サービスのロジックは1回だけ実装され、正しい表現の選択(Acceptヘッダー)+適切なレンダリング関数(またはテンプレート)へのディスパッチは、整然とした透過的な方法で行われます。
$ curl localhost:8080/x
<html><body>Hello, x!</body></html>
$ curl -H "Accept: application/html" localhost:8080/x
<html><body>Hello, x!</body></html>
$ curl -H "Accept: application/xml" localhost:8080/x
<message>Hello, x!</message>
$ curl -H "Accept: application/json" localhost:8080/x
{'message':'Hello, x!'}
$ curl -H "Accept: text/plain" localhost:8080/x
Hello, x!
更新(2012年4月):Djangoのクラスベースのビュー、CherryPyのMethodDispatcher、Flask and Bottleフレームワークに関する情報を追加。質問されたとき、どちらも存在しませんでした。
誰もフラスコに言及していません。
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():
return "Hello World!"
if __name__ == "__main__":
app.run()
私たちは、使用しているジャンゴを RESTful Webサービスのために。
Djangoには、そのままでは十分な粒度の十分な認証がありませんでした。私たちはDjango-RESTインターフェースを使用しました。[私たちはそれ以来、メンテナンスの悪夢となったほど多くの拡張を行ったので、独自に開発しました。]
人間向けのHTMLページを実装する「html」URLと、Webサービス指向の処理を実装する「json」URLの2種類のURLがあります。多くの場合、ビュー関数は次のようになります。
def someUsefulThing( request, object_id ):
# do some processing
return { a dictionary with results }
def htmlView( request, object_id ):
d = someUsefulThing( request, object_id )
render_to_response( 'template.html', d, ... )
def jsonView( request, object_id ):
d = someUsefulThing( request, object_id )
data = serializers.serialize( 'json', d['object'], fields=EXPOSED_FIELDS )
response = HttpResponse( data, status=200, content_type='application/json' )
response['Location']= reverse( 'some.path.to.this.view', kwargs={...} )
return response
重要なのは、便利な機能が2つのプレゼンテーションから除外されていることです。通常、JSONプレゼンテーションは、要求された1つのオブジェクトです。HTMLプレゼンテーションには、多くの場合、あらゆる種類のナビゲーション補助機能や、人々の生産性を高める他の状況に応じた手がかりが含まれています。
jsonView
機能は少しいらいらすることができ、すべての非常によく似ています。ただし、これはPythonなので、呼び出し可能なクラスの一部にするか、必要に応じてデコレータを記述します。
y = someUsefulThing(...)
が「ひどい繰り返し」の場合、すべての関数とメソッドへのすべての参照は「ひどい」です。関数を2回以上参照しないようにする方法がわかりません。
someUsefulThing(request, object_id)
データ検索式があります。これで、プログラムの異なるポイントに同じ式のコピーが2つあります。受け入れられた回答では、データ式は一度だけ書かれています。のsomeUsefulThing
ように長い文字列で呼び出しを置き換えpaginate(request, Post.objects.filter(deleted=False, owner=request.user).order_by('comment_count'))
、コードを見てください。それが私のポイントを説明してくれることを願っています。
Python Web Frameworks wikiを参照してください。
おそらく完全なスタックフレームワークは必要ありませんが、残りのリストはまだかなり長いです。
私はCherryPyが本当に好きです。以下は、安らかなWebサービスの例です。
import cherrypy
from cherrypy import expose
class Converter:
@expose
def index(self):
return "Hello World!"
@expose
def fahr_to_celc(self, degrees):
temp = (float(degrees) - 32) * 5 / 9
return "%.01f" % temp
@expose
def celc_to_fahr(self, degrees):
temp = float(degrees) * 9 / 5 + 32
return "%.01f" % temp
cherrypy.quickstart(Converter())
これは、CherryPyについて私が本当に気に入っている点を強調しています。これは完全に機能する例であり、フレームワークを知らない人でも非常に理解できます。このコードを実行すると、Webブラウザーで結果をすぐに確認できます。たとえば、http:// localhost:8080 / celc_to_fahr?degrees = 50にアクセスする122.0
と、Webブラウザに表示されます。
REST APIを公開するためだけにDjangoを使用する理由はありません。軽量で柔軟なソリューションがあります。Djangoは他の多くのことをテーブルに運びますが、それらは必ずしも必要ではありません。一部のコードをRESTサービスとして公開するだけの場合は、必要ありません。
私の個人的な経験、fwiwは、万能のフレームワークがあれば、簡単であるという理由だけでORMやプラグインなどの使用を開始し、すぐに依存関係が発生することです。それを取り除くのは非常に難しいです。
Webフレームワークの選択は難しい決断です。RESTAPIを公開するためだけにフルスタックソリューションを選択することは避けます。
ここで、本当にDjangoを使用する必要がある場合は、Pistonがdjangoアプリ用の優れたRESTフレームワークです。
そうは言っても、CherryPyも本当に見栄えが良いですが、RESTよりもRPCが多いようです。
サンプルを見ると(私は使ったことはありません)、RESTだけが必要な場合は、おそらくweb.pyが最適で最もクリーンです。
RESTに関するCherryPyドキュメントでの議論は次のとおりです:http : //docs.cherrypy.org/dev/progguide/REST.html
特に、HTTP動詞識別子(GET、POSTなど)に基づいてメソッドを呼び出す、MethodDispatcherと呼ばれる組み込みのCherryPyディスパッチャーについて言及しています。
あらゆる種類のPython WebフレームワークがRESTfulインターフェースを実装できるようになりました。
Djangoにとって、おいしいパイとピストンに加えて、django-rest-frameworkは注目に値する有望なものです。私のプロジェクトの1つは既にスムーズに移行しています。
Django RESTフレームワークはDjangoの軽量RESTフレームワークであり、適切に接続された、自己記述的なRESTful Web APIを簡単に構築できるようにすることを目的としています。
簡単な例:
from django.conf.urls.defaults import patterns, url
from djangorestframework.resources import ModelResource
from djangorestframework.views import ListOrCreateModelView, InstanceModelView
from myapp.models import MyModel
class MyResource(ModelResource):
model = MyModel
urlpatterns = patterns('',
url(r'^$', ListOrCreateModelView.as_view(resource=MyResource)),
url(r'^(?P<pk>[^/]+)/$', InstanceModelView.as_view(resource=MyResource)),
)
公式サイトの例を見てみましょう。上記のすべてのコードは、API、自己説明ドキュメント(SOAPベースのWebサービスなど)、さらにはサンドボックスを提供して、少しテストしています。とても便利です。
web2pyには、こことここ(ビデオ)で説明されている RESTful APIを簡単に構築するためのサポートが含まれています。特に、を見てくださいparse_as_rest
。これにより、リクエスト引数をデータベースクエリにマップするURLパターンを定義できます。およびsmart_query
、URLで任意の自然言語クエリを渡すことができます。
私はDjangoを使用しているので、django-pistonの代わりにdjango- tastypieを検討できます。ピストンよりも非ORMデータソースへのチューニングが簡単で、優れたドキュメントがあります。
厳密なRESTサービスのフレームワークに取り組んでいます。http://prestans.googlecode.comをご覧ください。
現在のところAlphaの初期段階では、mod_wsgiとGoogleのAppEngineに対してテストを行っています。
テスターとフィードバックを探しています。ありがとう。