【发布时间】:2014-04-02 17:32:09
【问题描述】:
我目前正在尝试使用 Tastypie 设计一个 API,但是当我处理相关的模型和资源时,我遇到了诸如“我应该使用 full=true 吗?为什么?”之类的设计问题。
如果帖子很长,请不要担心,这只是因为我试图解释事情:)
让我们以 3 个相关资源为例:
class UserResource(ModelResource):
class meta():
queryset = User.objects.all()
resource_name = 'users'
# Some other required fields
class ClientUserResource(ModelResource):
user = fields.ForeignKey(UserResource, 'user') # I could add full=True
class meta():
queryset = ClientUser.objects.all()
resource_name = 'client_users'
# Some other required fields
class CardResource(ModelResource):
linked_client = fields.ForeignKey(ClientResource, 'linked_client') # I could add full=True
class meta():
queryset = Card.objects.all()
resource_name = 'cards'
# Some other required fields
用这3个相关资源发出简单的GET请求来获取信息是没有问题的。
但是现在,想象一下每个资源都有自定义的 Authorization、Validation 以及其他可能被覆盖的方法,例如 obj_get_list() 或 dehydrate()。
如果我想获得一张卡及其用户的信息(我们假设我们需要的数据分布在 3 个资源中),让我们描述一下我们拥有的不同解决方案:
解决方案 A -> 1 个请求,在 FK 字段中使用 full=True
"http://myapp/api/v1/cards/42" 上的 GET 请求将为我提供所需的所有信息。
然而,在这种情况下,UserResource 和 ClientUserResource 的自定义 Authorization 方法将永远不会被调用。这意味着 API 用户将访问他们不应访问的信息。当然我可以在 CardResource 的 Authorization 方法中管理这个,但这确实是一件坏事(不是 DRY,不是它的作用)
解决方案 B -> 3 个“嵌套”级别的 3 个请求,FK 字段中的 full=False
-
"http://myapp/api/v1/cards/42"上的 GET 请求提供我的 uri 链接的 ClientUserResource。 - ClientUserResource 的 URI 上的 GET 请求为我提供链接的 UserResource 的 uri
- UserResource 的 URI 上的 GET 请求为我提供了我需要的数据 用户资源
我可以看到解决方案 B 的 2 个问题:
- 性能:如果我的模型更复杂,我需要执行大量请求
- 安全性:即使没有解决方案1那么糟糕,当你对一个列表发出GET请求,当答案是一个空列表,或者一个包含uris的列表(uris包含ids)时,它已经是信息。
在这种情况下,您会使用什么解决方案?你能看到更好的方法吗? 谢谢。
【问题讨论】: