3

我对不同的 Web 框架(Django、web.py、Pyramid 和 CherryPy)有一些经验,我想知道在哪个框架中更容易并且希望更清洁地实现路由调度程序到不同的“视图/处理程序”基于“接受”标头和 HTTP 方法,例如:

Accept: application/json
POST /post/

处理方式不同于:

Accept: text/html
POST /post/

因此,请求被路由到 MIME“application/json”和 HTTP 方法“POST”的相应处理程序的特定视图。

我确实知道如何在 CherryPy 中实现类似的东西,但是我失去了使用 CherryPy 工具来进行请求的内部重定向,因为我直接调用特定方法而不是从调度程序自动调用。另一种选择是从头开始实现一个全新的调度程序,但这是最后一个选择。

我知道在 url 中使用扩展名的替代方法,例如/post.jsonor /post/.json,但我希望保持相同的 url?

4

3 回答 3

12

如果您正在寻找的只是一个可以轻松完成此任务的框架,那么请使用pyramid.

Pyramid 视图定义由predicates组成,而不仅仅是路由,并且仅当所有谓词都匹配时,视图才匹配。一个这样的谓词是accept谓词,它完全符合您的要求。根据Accept标题轻松切换视图:

from pyramid.view import view_config

@view_config(route_name='some_api_name', request_method='POST', accept='application/json')
def handle_someapi_json(request):
    # return JSON

@view_config(route_name='some_api_name', request_method='POST', accept='text/html')
def handle_someapi_html(request):
    # return HTML
于 2012-12-22T15:00:27.330 回答
5

我需要在 Django 中执行此操作,因此我编写了一个中间件以使其成为可能:http ://baltaks.com/2013/01/route-requests-based-on-the-http-accept-header-in -django

这是代码:

# A simple middleware component that lets you use a single Django
# instance to serve multiple versions of your app, chosen by the client
# using the HTTP Accept header.
# In your settings.py, map a value you're looking for in the Accept header
# to a urls.py file.
# HTTP_HEADER_ROUTING_MIDDLEWARE_URLCONF_MAP = {
#     u'application/vnd.api-name.v1': 'app.urls_v1'
# }

from django.conf import settings

class HTTPHeaderRoutingMiddleware:

    def process_request(self, request):
        try:
            for content_type in settings.HTTP_HEADER_ROUTING_MIDDLEWARE_URLCONF_MAP:
                if (request.META['HTTP_ACCEPT'].find(content_type) != -1):
                    request.urlconf = settings.HTTP_HEADER_ROUTING_MIDDLEWARE_URLCONF_MAP[content_type]
        except KeyError:
            pass # use default urlconf (settings.ROOT_URLCONF)

    def process_response(self, request, response):
        return response
于 2013-01-15T04:37:46.510 回答
0

我不确定您所说的“内部重定向”是什么意思,但是如果您查看代码,您会发现 tools.accept 是一个非常薄的lib.cptools.accept包装器,您可以轻松地从自己的代码中调用它. 将您的服务器可以发送的 Content-Types 列表交给它,它会告诉您客户端更喜欢哪一个,或者如果您发出的类型和客户端接受的类型不重叠,则引发 406。

于 2012-12-22T00:19:23.410 回答