在库中包装第三方服务的最佳实践
我有兴趣为我正在使用的第三方 API 编写一个库,并且我需要一些建议。该库的平均使用会在一个请求中涉及多个 api 调用。例如,一次 api 调用从第三方服务获取用户,然后另一次调用使用该用户获取他/她的照片。每个 API 调用都会获得自己的库方法包装器,并带有额外的逻辑来处理错误/超时,但我最大的问题是该库是否应该作为包含状态的单例或仅作为一系列类方法。
例如:
user_id = ThirdParty.get_user("[email protected]")
photos = ThirdParty.get_photos(user_id)
或者
thirdpartyservice = ThirdPartyService.new("[email protected]")
photos = thirdpartyservice.get_photos
这些不一定是库的确切设计,但我只是对每种方法的优缺点感到困惑。任何帮助都会很棒!
顺便说一句,我正在使用红宝石!
I am interested in writing a library for a third party API I am using and I need some advice. The average use of the library will involve several api calls in one request. For example, one api call to grab a user from the third party service, and then another call to use that user to grab his/her photos. Each API call will get its own library method wrapper with additional logic to handle errors/timeouts, but my biggest question is whether the library should be made as a singleton that contains state or just as a series of class methods.
For example:
user_id = ThirdParty.get_user("[email protected]")
photos = ThirdParty.get_photos(user_id)
OR
thirdpartyservice = ThirdPartyService.new("[email protected]")
photos = thirdpartyservice.get_photos
These doesn't have to be the exact deseign of the library, but I just am confused about the pros/cons of each approach. Any help would be amazing!
Btw, I am using ruby!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我会让库包含状态,因为这会降低用户端代码的复杂性(这就是 API 应该做的,增加简单性)。通过这种方法,用户不必跟踪该 user_id,因为库会保留该状态。
如果用户确实想要他们的 user_id (或库存储的任何其他数据),您只需在库中创建一个
attr_reader
即可公开该数据。要为 get_photos 方法添加灵活性,您可以执行以下操作:
这种方式默认为存储的 id,但是它增加了灵活性,因为用户可以根据需要指定 userid。
I would have the library contain the state as this reduces the complexity of code on the user side(and that's what API are supposed to do, increase simplicity). With this approach, the user doesn't have to keep track of that user_id since the library is keeping state of that.
If the user really wanted their user_id (or any other data that the library stores), you can just create an
attr_reader
in your library to expose that data.To add fleixiblity for the get_photos method, you can do something like:
This way it defaults to the stored id, however it adds flexibility in that the user can specify the userid if he so chooses.
您需要状态(主机等)和基于该状态的行为,因此您应该使用对象,而不是一个单例对象。
如前所述,您不应命名诸如
get_photos
之类的方法,而应命名为photos
。You need state (host, etc) and behavior based on that state so you should use objects, not one singleton object.
As mentioned, you should not name methods like
get_photos
, justphotos
.我认为最佳实践是使用提供商和服务,以便能够不受特定服务提供商的束缚。您可能希望对其进行一些抽象,而不是简单地包装该库,并且默认情况下仅允许单个服务提供者。
尽管在像 Ruby 这样的动态/鸭类型语言中并不真正需要继承,但这可能有助于具体化“原因”。
然后,在您的代码中可以有这样的内容:
然后六个月后,当您的用户喜欢您的 Gem/库但需要 MailChimp 支持时,您可以简单地创建第二个服务“MailChimpService”并允许您的客户使用新的提供程序。
I believe the best practice is using provider and services for the ability to not be tied down to a specific service provider. Instead of simply wrapping the library you may want to abstract it a bit and by default only allow a single service provider.
Although inheritance isn't really needed in a dynamic/duck typed language like Ruby this may help concrete the 'why'.
Then, in your code you can have something like this:
Then six months later when your users love your Gem/library but want MailChimp support you can simply create a second service 'MailChimpService' and allow your clients to use the new provider.
使用 getter 和 setter 方法会比 get_set_ 方法更好。它是 ruby 标准(不确定,但 get_ 和 set_ 方法我只在 ruby 代码中看到过一次)。
如果您不需要在请求之间保存某些状态,请将其设为静态。但这取决于很多因素。您能告诉我们您需要包装哪些 API 吗?
Instead of get_ set_ methods will be better to use getters and setters. It is ruby standard (not sure, but get_ and set_ methods I saw only once in ruby code).
If you don't need to save some state between requests, make it static. But it depends on many factors. Can you tell us what API you need to wrap ?