库需要在Web会话中存储对象:关于API设计的建议

时间:2014-10-04 22:32:40

标签: python openid api-design

我正在开发一个OpenID消费者库[1],它在两个单独的Web请求中完成它的工作:

  1. 当用户请求身份验证时,库会从用户提供的URL中发现一些信息。
  2. 当库实际完成身份验证时,将在另一个Web请求期间使用此信息。
  3. 我想知道如何最好地设计库API以在两个请求之间保留“发现信息”:

    1. 我可以要求调用者为两个调用提供自己的会话对象,并且库将存储并从中读取自己的对象:

      result = openid.request(session, url) # stores discovery in `session`
      # ...
      openid.authenticate(session, auth_data) # reads discovery from `session`
      

      我不太喜欢它的美学,因为它看起来像一个控制反转:带上你自己的缓冲区,我们将为你使用它。此外,“会话”不是一个明确定义的接口,可能会暴露一些限制。例如,Django中的会话默认只希望存储JSON可序列化对象,而表示发现信息的对象是json无法识别的自定义类。

    2. 我可以将发现信息返回给调用者,让他们按照自己的意愿处理它:

      result, discovery = openid.request(url)
      session['openid.discovery'] = discovery
      # ...
      openid.authenticate(session['openid.discovery'], auth_data)
      

      这使库更清晰(不需要发明会话密钥名称或会话清理策略),但将此作业移动到调用者。如果调用者是另一个为Web框架实现OpenID行为的库代码,那么这可能没问题,但如果调用者是一个不应该被这种簿记困扰的应用程序开发人员则不行。

    3. 哪种方法最好(对于“最佳”的任何主观定义)?还有另外一个吗?

1 个答案:

答案 0 :(得分:1)

第二种方法肯定更清洁,因为:

  1. 正常的返回值总是优于" out"参数
  2. 它不会限制会话对象的格式(实际上,根本没有明确的会话对象)