【问题标题】:REST app architectureREST 应用架构
【发布时间】:2013-07-12 11:06:35
【问题描述】:

我正在开发一个 RESTful 应用程序,其目标是允许用户跟踪他在体育活动中的结果、进度和表现。

我想为此应用创建两个或更多客户端:

1) 网络客户端

2) 移动客户端(iOS / Android)

我正在 django 中使用 sweetpie 应用程序编写它,我想知道我是否应该在同一个应用程序中创建 Web 客户端,这将提供 RESTful api 或者我应该将其保留为纯 REST 服务并构建单独的 Web 客户端,这将通过api联系它?

就目前而言,我没有看到将两者合二为一的任何缺点,但我不是具有这种架构的程序的专家,所以我正在寻找一些建议,并在其背后进行论证。

【问题讨论】:

  • 单独的web客户端如何联系api?
  • 通过请求具有特定 URL 和正确 HTTP 请求类型的资源?例如,要获取某些用户的锻炼列表,它会将 GET 发送到 restapp/users/5/workouts。

标签: django rest architecture tastypie


【解决方案1】:

回答这个问题并不容易,因为这在很大程度上取决于您正在构建什么样的服务。

方法一:传统 Django 应用 + API

在这里,您的 Django-app 和 tastpie API 共享通用数据模型,但呈现方式不同。一种使用 Django 模板和视图,另一种使用 sweetpie。

优点:

  • 构建传统的 Web 服务是一个相对容易且易于理解的问题
    • Django 为此提供了很多工具

缺点:

  • 无法保证 API 提供与 Web 服务相同的功能
  • 您必须保持两种不同的方式与数据交互。

方法 2:仅 API + 使用 API 的 JavaScript webapp

通过tastypie API 提供的服务只有一个接口。 Web 客户端是使用 backbone.jsbackbone-tastypie 等 JavaScript 工具单独构建的。

优点:

  • 您保证第 3 方开发人员可以构建与您的 Web 服务具有相同功能的服务(请参阅 dogfooding)。
  • 如果您的服务更像是一个应用程序而不是页面集合,则效果会非常好。

缺点:

  • 客户端 JavaScript 工具不如 Django(例如模板)。
  • 模板的客户端渲染仅在加载大部分资源后发生。
    • 第一个页面加载很慢
  • IE9 之前的浏览器没有技巧就无法运行,IE9 可能需要技巧
  • 您确实需要注意浏览器缓存
  • SEO 不像传统网络服务那样简单。

方法 3:仅 API + 从 Django 视图调用 API

与方法 1 几乎相同,但不是直接使用您的模型,而是在内部调用 tastypie 资源。

优点:

  • 您仍然可以使用大多数 Django 工具。
  • 您大多使用与潜在的第 3 方开发人员相同的 API

缺点:

  • 我不知道这会产生多少开销。

【讨论】:

  • 谢谢,这很有帮助。我当然不会使用第一种方法,因为您指出功能应该是统一的,所以我不希望 Web 客户端(将通过模型直接与服务通信)和其他客户端(将与服务通信)有不同的行为通过 api )。我认为第二种方法是最好的,但我不知道你为什么建议 JavaScript web 应用程序 - imo 它可以是另一个 django 应用程序,它从“远程 api”而不是它自己的模型中检索数据。
  • 我发现了这个关于 REST 风格的演示文稿:slideshare.net/apigee/…,我认为第三种方法的缺点可能是限制了添加网关、负载平衡器和防火墙等功能,因为我们打破了分层系统的原则。
【解决方案2】:

还有第四种方法可以做到这一点,它在@seppo-erviälä 方法 1 和方法 2 上进行了扩展:

方法四:API View + Django View via Handler

创建一个返回 RESTful 资源的处理程序,就像通​​常的 RESTful API 视图一样。但是这个处理程序可以从任何地方调用。它获取视图获取的相同请求字典,并返回视图返回的相同 JSON。所以现在,架构是:

          Handler
         /   |   \
        /    |    \
       /     |     \
      /      |      \
RESTfulView  |    Normal Django View
             |
       Anything Else

处理程序:

class ResourceHandler:

    def create_resource(self, data):
        # code

    def fetch_resource(self, rId):
        # code

    # and so on

你从这样的视图中调用它:

# /views/restfulview.py
# using django-rest-framework
from rest_framework.response import Response

class RESTCallView(APIView):

    h = ResourceHandler()

    def get(self, request, rId):
        return Response(self.h.fetch_resource(rId))


# /views/normalview.py
from django.views.generic.base import TemplateView

class SomeDjangoView(TemplateView):

    h = ResourceHandler()

    def get(self, request, rId):
        return HttpResponse(self.h.fetch_resource(rId))

当然,这只是示例代码,并不是真正的 Python 语言,但你明白了。
我在一家大型电子商务公司工作,我的一些队友使用这种方法取得了巨大的成功。
其他一些优点是:

  • 现在迁移旧数据变得容易多了,因为您只需创建dict 并将其发送到Handler。同样,同步也变得容易得多。
  • 对 API 的更改集中在一处,您可以在不终止对数据的访问的情况下切断应用程序。

希望这对你也有帮助.. :)

【讨论】:

    【解决方案3】:

    最好创建一个纯 REST 服务并从客户端使用它。它将提供一个干净的分层架构,因为您不会在一个应用程序中将服务与客户端混合。通过单独拥有一个公共服务,您将拥有:关注点分离、架构整洁、布局正确、可读性和更好的可维护性。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-09
      • 1970-01-01
      • 2020-09-04
      • 1970-01-01
      • 2016-02-09
      • 1970-01-01
      相关资源
      最近更新 更多