通过 Hammock 进行 Facebook 集成






4.82/5 (9投票s)
最近,我区分了社区驱动库蓬勃发展的框架和 API 不断发展的 API。在本文中,我将举例说明如何使用 REST 库 Hammock 与 Facebook 进行集成。
引言
最近,我写了一篇关于社交媒体和集成策略的文章。我故意没有详细说明,因为我希望从更哲学的角度看待我们的开发流程。我区分了社区驱动库蓬勃发展的框架和 API 不断发展的 API。后者经常成为项目的“致命伤”。
我相信我们需要改变与社交媒体 API 合作的方式,停止尝试用我们选择的技术为这些 API 创建 SDK。技术发展太快了,取而代之的是,我们需要拥抱核心技术,同时保持集成层的轻量级。
在本文中,我想通过演示与 Facebook 的一些集成来举例说明一种方法。这里的关键点是,我不是使用许多 .NET 库中的一个来封装 Facebook API,而是使用一个与 Facebook API 本身完全解耦的通用库。
Hammock - REST,简单易用
Hammock 是一个用 .NET 构建的开源项目,它以通用的方式促进 RESTful 服务的消费。它支持异步操作、查询缓存、模拟和速率限制等功能。当然,还有其他库也可以使用。
代码
以下是在 ASP.NET 中检索用户墙帖子的示例。我们可以仅通过 JavaScript 实现相同的功能,但假设我们想在服务器端处理数据。这要求用户已向 Facebook 应用程序授予 read_stream
权限,并假定用户已通过身份验证。在提供的源代码中,我已展示了如何轻松地通过社交插件和 JavaScript 实现这两个任务。
我们需要做的第一件事是创建 Hammock 的 RestClient
类实例。它包含服务终结点 (EndPoint) 的基本 URI,还可以包含其他默认属性,例如 UserAgent
字符串。
IRestClient client = new RestClient
{
Authority = "https://graph.facebook.com/",
UserAgent = "MyFacebookApp"
};
接下来,我们创建 Hammock 的 RestRequest
类实例。这允许我们对相对于上面定义的基本终结点 URI 的特定路径发出 RESTful 调用。使用 Hammock 的 API,可以轻松地将请求参数添加到调用中。在这种情况下,用户的 access_token
会附加到查询字符串以提供必要的授权。
// call https://graph.facebook.com/[userid]/feed
var request = new RestRequest
{
Path = string.Concat(UserId, "/feed"),
Method = WebMethod.Get
};
request.AddParameter("access_token", AccessToken);
请注意,上面示例中显示的 UserId
和 AccessToken
值是从当前已通过身份验证的 Facebook 用户获取的。在提供的源代码中,我将这些值从由社交插件登录事件触发的 Ajax 调用中传递。
到目前为止,很简单,对吧?Facebook API 的任何更改都可以让我们快速添加或删除发送到 API 的参数。
下一步是发出请求并解析响应。这可以通过我们之前创建的 RestClient
来完成。
var response = client.Request(request);
// check for errors and do something
if (response.StatusCode != HttpStatusCode.OK)
{
throw new CommunicationException(
string.Format("The EndPoint {0}{1} returned an unexpected StatusCode {2}",
client.Authority, client.Path, response.StatusCode));
}
// this is the raw JSON response
var content = response.Content;
好了,现在是重点,我在这里要重申我的观点,即保持其轻量级和松散耦合。我们可以使用 Hammock 的反序列化器将响应直接键入到我们自己的对象中,但这对我来说太死板了。我宁愿使用动态类型。这允许我们以松散的方式访问 JSON 属性,如果 API 更新,可以更轻松地进行更改。
我无法弄清楚如何让 Hammock 的开箱即用反序列化与动态对象一起工作。这可能是可能的,如果有人知道,请告诉我。相反,我创建了自己的 JavaScriptConverter
扩展,以便可以使用 .NET 内置的 JavaScriptSerializer
类。您也可以通过 Hammock 的接口注册自己的自定义反序列化类,但我已保持简单。
// set up deserialization classes
JavaScriptSerializer serializer = new JavaScriptSerializer();
serializer.RegisterConverters(new[] { new JsonConverter() });
// deserialize the raw JSON
dynamic result = serializer.Deserialize<ExpandoObject>(response.Content);
// parse the results
foreach (dynamic obj in result.data)
{
Response.Write(obj.from.name + " wrote " + obj.message);
}
静态类型与动态类型
ExpandoObject
的好处是,它不仅提供了对响应对象的动态访问以保持松散耦合,而且还实现了 IDictionary<string, object>
。这意味着可以使用 JavaScriptSerializer
轻松地将其转换为类型化的对象。如果我们决定将代码移到服务层并想为我们的业务层提供强类型模型,这将非常有用。只有源对象和目标对象上都定义的属性才会在转换过程中进行映射,其他属性将被忽略。
// define a class for post content
public class Post
{
public string Id { get; set; }
public string Message { get; set; }
}
foreach (var obj in result.data)
{
// convert ExpandoObject to the Post class
var post = serializer.ConvertToType<Post>(obj);
// we now have strong typed access to content
var message = post.Message;
}
运行演示
要运行随附的演示代码,您应该在 FBHelper
类中用您自己的 Facebook 应用程序密钥替换 Facebook AppId
的值。有关如何获取此信息的更多详细信息,请参阅 Facebook 文档。
您会注意到在提供的源代码中,我创建了一个名为 JsonExpandoObject
的自定义 expando 类。这是因为如果您尝试访问不存在的属性,ExpandoObject
会抛出异常。我的版本会返回 null
,因此与 JSON 的兼容性更好。
摘要
总而言之,像 Hammock 这样的通用第三方库可以用来加速与社交媒体 API 的集成。与第三方社交媒体 SDK 相比,它的优点是使代码库更加松散耦合。通过这样做,它允许开发人员围绕长期建立的核心技术构建应用程序,并产生一个更易于适应变化的 codebase。
通过实现动态类型的后期绑定,您可以进一步解耦对 API 的硬依赖。这对于数据层中内容的轻量级操作特别有用。要将对象传递到业务层,我已展示了如何使用 JavaScriptSerializer
快速将动态类型转换为所需的静态类型。
静态类型当然是在编译时检查的,并且提供了许多优于动态类型的优点。这里的诀窍在于,我们能够在业务层中利用静态类型,但可以从后期绑定到 API 代码的对象进行映射/转换。此映射/转换代码成为 API 更改时维护的单一接触点。
包含的示例还展示了我们如何利用新兴的社交插件和 JavaScript API,这些 API 对更改更具弹性。这些可以用于核心功能,并且在可能的情况下应始终优先使用。