gpt4 book ai didi

python - Python对象层次结构和REST资源?

转载 作者:太空宇宙 更新时间:2023-11-04 10:58:42 25 4
gpt4 key购买 nike

我目前在使用REST API的Python应用程序(使用Twisted)中遇到一个“体系结构”问题,我正在寻找反馈。

警告 !长篇文章!

让我们假设以下对象层次结构:

class Device(object):
def __init__():
self._driver=Driver()
self._status=Status()
self._tasks=TaskManager()

def __getattr__(self, attr_name):
if hasattr(self._tasks, attr_name):
return getattr(self._tasks, attr_name)
else:
raise AttributeError(attr_name)

class Driver(object):
def __init__(self):
self._status=DriverStatus()

def connect(self):
"""some code here"""

def disconnect(self):
"""some code here"""

class DriverStatus(object):
def __init__(self):
self._isConnected=False
self._isPluggedIn=False


我还有一个很深的对象层次结构(以上元素只是其中的一个子部分),所以,现在,这给了我以下其余api中的资源(我知道,其余不是关于URL层次结构,而是媒体类型,但这是为了简单起见):

/休息/环境

/ rest / environments / {id}

/ rest / environments / {id} / devices /

/ rest / environments / {id} / devices / {deviceId}

/ rest / environments / {id} / devices / {deviceId} / driver

/ rest / environments / {id} / devices / {deviceId} / driver / driverstatus

几个月后,我从“脏”肥皂类型Api切换回REST,但我不确定如何处理似乎增加的复杂性:


REST资源/媒体类型的泛滥:例如,我现在不仅拥有设备资源,还拥有所有这些资源:


设备
设备状态
司机
驾驶员状态


从Resfull的观点来看,所有这些都是合理的,但每个子表都映射到一个单独的python类是否有很多子资源正常吗?
将一个方法丰富的应用程序核心映射到一个Rest-Full api:在Rest资源中,资源应该是名词,而不是动词:是否有良好的规则/技巧从各个方法集中定义一组资源? (到目前为止,我发现的最全面的示例似乎是 this article
Api逻辑会影响应用程序的结构:应用程序的API逻辑是否应至少部分指导其某些内部逻辑,还是应用关注点分离的良好实践?即,我是否应该具有一个中间层的“资源”对象,它们可以与应用程序核心进行通信,但不能将一对一映射到该核心的类?
如何以一种完全正常的方式正确处理以下内容:我需要能够在客户端中显示可用驱动程序类型的列表(即类名,而不是驱动程序实例):这是否意味着还要创建另一种资源,例如“ DriverTypes ?


这些问题比较冗长,因此,感谢您的耐心配合,我们欢迎任何指教,反馈和批评!



致S.Lott:


我所说的“资源过于分散”是指,许多不同的子资源基本上仍然适用于同一服务器端实体
对于“连接”:那么这将是“ DriverStatus”资源的修改版本吗?我认为连接一直存在,因此使用“ PUT”,但是考虑到“ PUT”应该是幂等的,那会是一件坏事吗?
您对“停止编码和重新思考”是正确的,这就是我在纸上询问所有这些问题并将其放下来以得到更好的概述的原因。

-事情是,现在,您所说的基本“现实世界对象”对我来说是休息资源/资源集合,并且可以通过POST,GET,UPDATE,DELETE正确地进行操作,但是我很难是时候把我本能地不视为“资源”的事情带入“休息”方法。

最佳答案

规则1. REST与对象有关。不是方法。


  REST“资源”变得过于分散


假。总是错误的。 REST资源是独立的。它们不能太“分散”。


  我现在不仅拥有设备资源,还拥有所有这些资源:
  
  设备DeviceStatus驱动程序DriverStatus
  
  虽然这些都说得通
  从[RESTful]的角度来看,有很多子对象是正常的
  每个映射到单独的python类的资源?


实际上,它们没有任何意义。因此,您的问题。

设备是一回事。 / rest / environments / {id} / devices / {deviceId}

它具有状态。您应该考虑将状态和设备信息一起提供为描述设备的单个复合文档。

仅仅因为您的关系数据库已被规范化并不意味着您的RESTful对象就需要与数据库一样精确地进行规范化。尽管它更简单(许多框架使它非常非常简单),但它可能没有意义。


  认为连接始终存在,因此使用“ PUT”
  ,但是考虑到“ PUT”应该是幂等的,这会不好吗?


连接并不总是存在。他们可能来来去去。

虽然关系数据库可能具有可以更新的多对多关联表,但这是一种特殊的情况,在DBA的世界之外并没有多大意义。

两个RESTful事物之间的联系很少是单独的事物。这是每个RESTful事物的属性。

完全不清楚这个“连接”是什么。您对此含糊其词,但未提供任何细节。

缺少任何可用的事实,我想您是将设备连接到驱动程序,并且存在某种[Device]<-[Driver Status]->[Driver]关系。从设备到驱动程序的连接可以是单独的RESTful资源。

它可以很容易地成为设备或驱动程序的属性,而该属性实际上没有单独的可见的RESTful资源。

[再次。诸如Django-Piston之类的某些框架使简单地暴露基础类变得微不足道。但是,这可能并不总是合适的。]


  有好的规则/技巧可以从一组方法中巧妙地定义一组资源吗?


是。不要这样资源不是方法。就是这样。

如果您有很多方法(在CRUD之外),那么您可能会遇到数据模型问题。您在关系模型中表达的事物类别可能太少,而事物的状态更新也太多。

有状态的对象并不是天生就邪恶的,但是需要对其进行严格的检查。在某些情况下,用于更改对象状态的PUT可能应该是POST,以添加到对象的历史记录中。 “当前”状态是最后发布的内容。

也。

您不必将每种资源都视为一类事物。您可以拥有作为集合的资源。您可以将相当复杂的文档发布到复合(适当地是Facade)的“资源”中。该复杂的文档可能意味着数据库中会进行多个CRUD操作。

您正在远离简单的RESTful。您的问题仍然是故意含糊的。 “方法丰富的应用程序核心”意义不大。没有具体的例子,就无法想象。


  api逻辑会影响应用程序结构


如果这些有所不同,那么您可能正在创建不必要的,无价值的复杂性。


  分离关注点是一种好习惯吗?


总是。为什么这么问?


  这很多似乎来自于我的困惑,即我如何将一个方法丰富的api映射到Rest-Full API,其中资源应该是名词,而不是动词:那么什么时候将一个元素视为rest“资源”是明智的?


资源由您的问题域定义。通常这是有形的。这些方法(例如“富含方法的API”中的方法通常是无关紧要的。它们是CRUD(创建,检索,更新,删除)操作。如果您的内容本质上不是CRUD,则必须停止编码。停止编写代码,以及重新考虑API以使其类似于CRUD。

CRUD-创建,检索,更新,删除映射到REST的POST-PUT-DELETE。如果您不能将问题域改写为这些术语,请停止编码。停止编码,直到获得CRUD规则为止。


  我需要能够在客户端中显示可用驱动程序类型的列表(即类名,而不是Driver实例):这是否意味着创建另一个资源,例如“ DriverTypes”?


正确。它们已经属于您的问题领域。您已经定义了此类。您只是通过REST使它可用。



这就是重点。问题域具有实际对象。您有类定义。他们是有形的东西。 REST转移那些有形事物的状态。

您的软件可能包含无形的东西,例如“关联”或“链接”或“连接”,这是软件解决方案的一部分。这个垃圾并不重要。它是实现细节。不是现实世界的东西。

从两个真实世界的RESTful资源中总是可以看到“关联”。一个资源可能具有类似外键的引用,该引用允许客户端对另一个相关对象进行RESTful提取。或者资源可能具有其他相关对象的集合,并且单个GET检索对象和相关对象的集合。

无论哪种方式,都可以使用真实的RESTful资源。该关系只是暗含的。即使它是一个物理上的多对多数据库表,也并不意味着它必须公开。 [再次。一些框架使公开所有内容变得轻而易举。这并不总是很好。]

关于python - Python对象层次结构和REST资源?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7614869/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com