锻造坊: Bloglines Web服务
上个月,我们研究了如何从许多不同的网站收集或聚合内容,并将它们整合为当日新闻的单一摘要。尽管看到我们用少量代码就能完成这么多工作令人惊叹,但我展示的应用程序与实际的聚合器相比,仅仅是个玩具。我的示例应用程序仅支持一个用户,由一个原始的配置文件控制,不将Weblog分类成组,仅在我们明确要求时才检查Weblog更新,并且不检查或处理错误。
考虑到技术和设计细节的必要性,创建一个健壮、用户友好的聚合器超出了本专栏的范围。但在我坐下来撰写本专栏的几天前,发生了一件令人惊叹的事情。免费的、基于Web的Bloglines.com聚合服务,许多人使用它来跟踪他们最喜欢的Weblog,宣布推出Web服务API,允许独立开发者创建和部署使用Bloglines开发的数据和应用程序的应用程序。Bloglines API的发布和可用性标志着Web服务在知名网站中日益普及,并为基于底层Bloglines基础设施构建的新应用程序打开了大门。
本月,我们将了解Bloglines API,包括基于它创建一个简单的应用程序。API在撰写本文时(2004年10月初)还是全新的,随着更多人使用它,无疑会不断发展。如果您对Weblog感兴趣,并且仍在等待看到Web服务的实际用途,那么这些事件的结合可能来得正是时候。
Web服务背后的基本思想非常简单:Web的成功很大程度上归功于客户端和服务器操作系统无关紧要这一事实。只要客户端和服务器遵守HTTP和HTML规范,它们就可以无缝通信。Linux正因如此才得以打入服务器领域。
Web服务更进一步,认为计算机而不是人应该成为Web的最大用户。尽管计算机通过HTTP交换信息,但它们以XML(标记语言或元语言)发送和接收数据,这种语言近年来像野火一样蔓延开来。如果我的计算机可以在发送到您的计算机的HTTP请求中发送XML,并且您的计算机然后在HTTP响应中返回XML,那么无论我们使用什么语言和操作系统,我们都可以交换信息。
这种服务的原始形式,称为XML-RPC,仍然存在,并且非常适合快速、轻松的通信。但是这个想法被进一步扩展,引入了XML-RPC缺乏的各种数据类型、错误检查机制和对象序列化技术。这种扩展被称为SOAP(简单对象访问协议)。SOAP理论上可以在各种协议之上运行,但它最常通过HTTP发送。
SOAP是许多问题的绝佳解决方案,但它非常复杂,速度可能很慢,并且难以实现。而且,XML-RPC和SOAP都要求HTTP请求包含一个格式良好的XML请求,其中包含查询。对这种日益增长的复杂性的一个回应是REST(具象状态传输),其中所有事务都由一个简单的HTTP GET请求发起,所有参数都在URL本身中指定。然后,响应是一个XML文档,其中包含与请求相关的记录和字段。所有Bloglines API调用都是通过REST完成的,尽管很难说这反映了现在提供的相对简单的查询,还是开发人员的设计偏好。
尽管Web服务可能正在公司内部兴起,但只有少数大型网站公开了他们的计划和API。最著名的例子是一些Web上最大、最赚钱的网站,包括亚马逊、eBay和谷歌。eBay对其Web服务的访问收费,包括年费和每次交易成本。相比之下,亚马逊和谷歌已将其API免费提供给公众,但受使用限制约束,并且不对未来的可用性做出任何承诺。
通过公开其API,Bloglines表明其有兴趣创建与亚马逊、谷歌和eBay已创建的同类开发者社区。此举也表明其有兴趣继续保持在Weblog聚合和应用程序领域的领导者地位。鉴于谷歌几年前收购了Blogger,以及Bloglines通过其API提供的广泛搜索功能,我们可能正在见证一种新型应用程序或平台之争的开始,谷歌和Bloglines API正在争夺关注。
Bloglines聚合来自大量Weblog和频繁更新的新闻来源的内容。Bloglines很高兴接受各种格式的订阅源,包括Atom和多个版本的RSS。实际上,如果提供多个订阅源,Bloglines为订阅者提供了选择使用哪个订阅源的选项。然后,Bloglines软件会存档该内容,为感兴趣的用户提供搜索界面。Bloglines提供了一些相关性功能,告诉订阅者哪些额外的Weblog可能让他们感兴趣。最后,Bloglines允许您查看其他用户的订阅;如果您有兴趣了解哪些Weblog让我感兴趣,您可以查看我的个人资料并查看我的订阅。
至少目前,大部分此功能仍然处于保密状态,只能通过Bloglines网站获得。但是,现在可以从Bloglines Web服务API获得三个特定的功能
Notifier:如果您是Bloglines订阅者,并且想知道何时从您订阅的一个或多个Weblog收到新内容,那么您现在可以做到这一点。这是Bloglines Web服务中最成熟的服务,许多用于多种操作系统和窗口工具包的工具都依赖此接口来提供更新。
Sync API:允许您检索有关特定用户的订阅信息,以及来自每个订阅的最新条目。您可以将其视为Bloglines为其提供的主要Weblog列表生成的HTML的基础数据。
Blogroll API:提供了一种检索和显示特定用户的订阅列表的方法。
正如我上面所写的,Bloglines已决定对所有Web服务API使用REST。这意味着每个请求都由一个URL组成,所有参数及其值都在URL中。信息以服务器认为合适的任何格式返回。这与SOAP形成鲜明对比,SOAP指定每个参数和返回值的名称和类型。此规则的一个小例外是,需要身份验证的API期望用户名和密码以HTTP Basic而不是URL本身的形式到达。在Bloglines的世界中,订阅者通过他们的电子邮件地址和用户选择的密码来识别。
在所有API中,Notifier是最容易理解和使用的。要调用Notifier,只需访问URL rpc.bloglines.com/update?user=reuven@lerner.co.il&ver=1。响应虽然(不正确地)被服务器标记为具有text/html的MIME类型,但包含格式为纯文本响应
|A|B|
Notifier可以按如下方式解释响应
通常,A表示用户订阅中未读Weblog条目的数量。
如果提供的电子邮件地址未在系统中注册,则A包含-1。
如果B不为空,则它包含一个指向升级页面的URL。文档没有过多说明拥有升级页面意味着什么。我假设这样的页面是为人员而不是程序设计的,因为要识别所有使用Notifier API并且需要升级的程序是不可能的,或者至少非常困难。
我们可以轻松地在任何现代高级语言中实现Notifier API的客户端。但在撰写本文时,已经存在Perl、Python和Ruby版本的Bloglines客户端库。我使用Perl版本(在CPAN上为WebService::Bloglines),但您可能会觉得更喜欢自己编写版本,使用不同的版本或两者都用。
这是一个简单的命令行程序,如果Bloglines报告有新消息等待,则打印“您有新的博客!”,如果我已经阅读了所有内容,则打印“没有新的博客”
#!/usr/bin/perl use WebService::Bloglines; my $username = 'reuven@lerner.co.il'; my $password = 'MYPASS'; my $bloglines = WebService::Bloglines->new( username => $username, password => $password); my $unread_blogs = $bloglines->notify(); if ($unread_blogs) { print "You have '$unread_blogs' new blogs!\n "; } else { print "No new blogs.\n" }
由以下代码返回的数字$bloglines->notify()是未读帖子数,而不是未读Weblog数。如果有来自五个Weblog的15条未读消息,$bloglines->notify()返回15,而不是5。此外,该数字反映了内部Bloglines数据库的状态。也就是说,如果您单击Weblog条目底部的“保留新消息”复选框,它将包含在以下代码返回的新消息计数中$bloglines->notify().
如果我们输入错误的用户名,我们的程序将以致命错误退出,并指示我们给出了错误的用户名。给出错误的密码对Notifier API没有影响,因为该信息是公开可用的。
正如我们之前提到的,Bloglines的另一个产品是Blogroll API。blogroll是特定作者认为有趣且经常阅读的Weblog列表。很可能,如果您喜欢阅读某人的Weblog,您也会喜欢浏览该人的阅读列表。在Bloglines的情况下,blogroll只是与特定用户关联的订阅列表。
到目前为止,我们已经提到某人的Bloglines用户名与他或她的电子邮件地址相同。但这并不完全正确——如果您选择将Bloglines用于您自己的私人目的,从不与他人分享有关您的订阅的信息,您只需要您的电子邮件地址。但如果您确实想公开您的订阅,您必须选择一个可以与之关联的用户名。就我而言,我的注册电子邮件地址是reuven@lerner.co.il,我的用户名是reuven。在我使用Bloglines的最初几个月里,这种区别对我来说并不清楚,尽管现在看来它被更明显地宣传了。
如果用户已建立用于公开消费的用户名,并且如果该用户已选择共享他或她的订阅,您可以按如下方式获取使用HTML和JavaScript的用户Blogroll版本:http://www.bloglines.com/public/reuven。如果我们想以HTML格式检索blogroll结果,我们可以使用以下URL样式:http://rpc.bloglines.com/blogroll?id=reuven&html=1。
但是Web服务的全部想法是使数据可机读,以便计算机可以存储和处理它。OPML(大纲处理器标记语言)是Dave Winer在2000年指定的,是Bloglines在导出订阅列表时使用的格式。它不是Bloglines Web服务规范的官方部分,但您可以通过访问以下类型的URL来检索它:http://www.bloglines.com/export?id=reuven。
在以上所有示例中,您可以并且应该将我的Bloglines用户名替换为您要阅读其blogroll的用户的用户名。并非每个用户都公开其订阅列表,因此在尝试检索它们时可能会遇到错误消息。一旦您检索到OPML,您需要处理它,可能使用诸如CPAN上公开可用的XML::OPML模块之类的工具。
Reuven M. Lerner,一位长期的Web/数据库顾问和开发人员,现在是西北大学学习科学项目的研究生。他的Weblog位于altneuland.lerner.co.il,您可以通过reuven@lerner.co.il与他联系。