【问题标题】:Implementing RPC in RESTful API using DRF使用 DRF 在 RESTful API 中实现 RPC
【发布时间】:2014-12-16 19:24:34
【问题描述】:

我正在使用 Django Rest Framework 来展示 RESTful API。我有一个路由器/视图集/序列化器为 Person 资源创建端点:

/api/People/<id>/

我想通过某种方式触发对此资源的非幂等操作(例如send-email-to)。我必须这样做而不必重新做很多路由/序列化基础设施的一个想法是向序列化程序添加一个只写布尔字段:

class PersonSerializer(serializers.ModelSerializer):
   send_email = serializers.BooleanField(write_only=True, required=False)

然后给模型添加只写属性:

class Person(models.Model):
  ...
  def do_send_email(self, value):
    # We also need to check the object is fully constructed here, I think
    if do_send_email:
        ...
  send_email = property(fset=do_send_email)

然后我可以PATCH 使用send_email=True 的有效载荷到达终点。

这是使用 REST API 完成类似 RPC 的功能的最佳方式吗?这是在 DRF 中完成此任务的最佳方法吗?理想情况下,我希望尽可能少地解决这个问题(即查看解决方案的代码行数)。 send-email-to 不是我想要处理的唯一操作。

【问题讨论】:

    标签: django rest django-rest-framework


    【解决方案1】:

    您可以使用extra actions drf 提供的。在你的情况下,我会使用@detail_route。

    类似的东西:

    @detail_route(methods=['post'])
    def send_mail(self, request, pk=None):
        send_mail_to(pk)  # Write here your email function.
    

    您必须在 Person 视图集中定义此函数,因此,为了调用此函数,您必须在 /people/{person_id}/send_mail POST其中 {person_id} 是此人的主键。

    附带说明,由于此函数是从客户端同步调用的,可能需要一段时间才能回答,我建议您使用celery。这将允许您异步调用 send_mail_to 函数而不会延迟用户响应。

    【讨论】:

    • 假设我希望send_mail 过程将subjectString)和retry_countint)作为参数。我希望它们在POST 有效负载中传递。我想使用Serializer 将有效负载解码到相应的字段。查看您发送的链接以及:django-rest-framework.org/api-guide/viewsets,这两个示例都显示使用PasswordSerializer 来解码有效负载。我将如何编写Serializer 来解码这种自定义消息格式(有两个字段:主题和重试计数)?大概,我没有像这样的现有Model
    • 好的。解决方案是继承 Serializer 而不是 ModelSerializer
    • 确实,如果你要解析的数据与模型本身不同,你需要定义一个自定义的序列化器。但是,您不需要定义模型,只需定义具有您需要的两个字段的序列化程序。
    猜你喜欢
    • 2014-10-07
    • 1970-01-01
    • 2017-12-10
    • 2014-03-27
    • 1970-01-01
    • 2017-03-21
    • 1970-01-01
    • 2014-08-08
    • 1970-01-01
    相关资源
    最近更新 更多