我正在编写Django应用程序,在这个应用程序中,我们将拥有多个调用第三方API的客户端库。当调用不同的端点时,我们希望能够确定在运行时加载哪个客户端库。我正试图确定最能做到这一点的Django/Pythonic方法
当前的思想是将类名存储在模型字段中,在视图中查询模型,并将类名传递给服务工厂,后者实例化相关服务并进行查询。我还考虑过编写一个使用反射查询类名的模型方法
例如,假设我们有一个名为Exchange的模型,它具有一个id、一个名称,并存储客户端名称。
class Exchange(models.Model):
exchange_name = models.CharField(max_length=255)
client_name = models.CharField(max_length=255)
def __str__(self):
return self.exchange_name那么在“视图”中,我们可能会看到这样的内容:
from rest_framework.views import APIView
from MyProject.trades.models import Exchange
from django.http import Http404
from MyProject.services import *
class GetLatestPrice(APIView):
def get_object(self, pk):
try:
exchange = Exchange.objects.get(pk=pk)
except Exchange.DoesNotExist:
raise Http404
def get(self, request, pk, format=None):
exchange = self.get_objectt(pk)
service = service_factory.get_service(exchange.client_name)
latest_price = service.get_latest_price()
serializer = PriceSerializer(latest_price)
return Response(serializer.data)这个语法可能并不完美,但还没有经过测试。但我们的想法是也许我们
ExchangeA - client1
ExchangeB - client2
ExchangeC - client3对于每个客户端,我们都有一个服务类,它们都是从同一个抽象库继承的。每个服务都有相同的覆盖。这样,当您调用/api/get_latest_price时,您将Exchange id作为查询param传递,并且代码加载任何与服务和客户端库相关的服务。这样我们就可以轻松地向系统添加新类型,具有一致和小的视图,并将业务逻辑解耦。这是一个可接受的,可伸缩的pythonic方法吗?还是有更好的解决方案?本质上,问题是在django中实现多态性,并将域模型与数据模型分离。这必须是一个解决的问题,所以我很好奇其他人可能会这样做。我知道像这样调用第三方API是不寻常的,但是由于我们被迫这样做,我想以尽可能干净、最可伸缩的方式来实现它。
发布于 2019-07-30 08:54:49
TL;DR
没有银弹。
更有用的答案:
没有通用和方便的方法来解决你的问题。解决方案可能因客户端库和第三方API的实现而有很大差异。如果它们都是相似的,你可以使用你的方法,你会没事的。如果API有一些不同,例如,一个API没有端点来获得最新的价格,那么您需要找到一些解决办法。如果API在工作流方面有很大差异,您需要找到完全不同的方法,例如,如果一个API可以立即返回报告,而另一些API在5分钟后通过回调返回报表,则需要找到解决办法。
因此,我能给您的一个真正的建议是检查第三方API之间的差异,并更多地关注您自己的项目的最高抽象的设计,这将使用低级别的客户机库。尽量减少第三方之间的差异对您的项目的影响。
发布于 2019-07-30 12:04:19
这里有类似的情况(以及其他一些密切相关的情况),并使用这种模式:将"service“类的名称存储在模型中,并使用一些注册表(您的"service_factory")来获取该类。It JustWorks(tm),没有人(来自不同的开发人员加入--并最终离开)抱怨过这个设计,也没有提出过任何更好的解决方案,到目前为止,我们遇到的唯一的小问题就是处理仍然从数据库中引用的“已停止的”服务(这也确实不是火箭科学)。
FWIW,这主要是“策略”设计模式的一个变体,我真的无法想象有一个更好的(“更好”=“更简单、更有效和更易于维护”)解决方案。
编辑
请注意,我的上述答案假设Exchange有其他在您的问题中没有提到的响应--否则,正如Alexandr所说的,这个模型似乎相当无用;)
https://stackoverflow.com/questions/57266619
复制相似问题