如何开发Manyou API客户端

出自Manyou开发者指南

跳转到: 导航, 搜索

Manyou发布了REST风格的API,提供用户、好友、Feed、个人主页和通知等五个类别的功能。 但目前仅提供PHP版本的客户端。

本文介绍Manyou API客户端的原理,相信熟悉其它开发语言(如Java、C#和Ruby等)的朋友看了之后,可以自行开发一个API客户端。

目录

API调用原理

Image:myop.gif

原理图


如图所示,运行着App的服务器是Manyou API的客户端(Client),MYOP服务器是Manyou API的服务端(Server)。

在用户访问某个App时,MYOP服务器会发送一些必要的参数给App服务器,以供App确认当前访问App的用户来自于合法的UCenter Home站点。(图中第1步)

在App运行时,如果需要从服务器端获取信息(例如判断当前登录用户的id),首先要向服务器端发送一个请求(图中第2步);服务器端接收到请求后,判断该请求是否合法(是否是由经过授权的App发送的,参数是否正确并完整等等)。如果请求合法,则服务器端调用对应的方法,并将执行结果返回给客户端(图中第3步)。

如果开发者的App采用MYML模式,MYOP服务器会通过POST方式把参数传递给App;如果采用的是Iframe模式,则MYOP服务器会通过GET方式把这些参数传递给App。

开发者可以在App中读取相应的POST或GET变量,即可得到由MYOP服务器发送的参数。例如MYML模式的App读取POST变量数组,可能得到以下结果:

Array ( [my_sig_uId] => 1042987 [my_sig_sId] => 100 [my_sig_time] => 1217839600 [my_sig_sessionId] => 4896c1f0000fea2ba38bc94ee52a06f6 [my_sig_friends] => 1000349,1000385,1000406,1000439,1000453,1000543 [my_sig_added] => 1 [my_sig_prefix] => http://uchome.developer.manyou.com/uchome/ [my_sig_appId] => 1001924 [my_sig_in_canvas] => 1 [my_sig_v] => 0.1 [my_sig_key] => 6dfd0d813065d32bba6da9226643add9 )

这些参数的含义如下:

[my_sig_uId] : 当前访问用户在Manyou平台上的用户Id(注意不是UCenter Home上的用户Id) [my_sig_sId] : 当前UCenter Home站点的Id [my_sig_time] : 生成签名的时间 [my_sig_sessionId] : 当前用户在Manyou上的session Id [my_sig_friends] : 当前用户的好友列表 [my_sig_added] : 当前用户是否已经添加本应用 [my_sig_prefix] : 当前UCenter Home站点的URL前缀 [my_sig_appId] : 当前App的Id [my_sig_in_canvas] : 是否在Canvas中 [my_sig_v] : 0.1 API客户端版本 [my_sig_key] : 数字签名

使用Iframe模式的App,得到的参数与MYML方式基本相同(除了my_sig_in_canvas会变成my_sig_in_iframe),但要从GET变量中取得这些参数而非从POST变量从获得。

API调用过程

那么,API客户端如何向服务器端发送请求呢? 发送的请求又应当是什么形式呢?

例如Manyou API提供user.getInfo方法,用于获取指定用户的信息。 下面以此例说明如何向服务器发送请求。

首先查看API文档,了解本方法的调用细节: http://wiki.developer.manyou.com/wiki/index.php/User.getInfo

文档中介绍需要向服务器端POST以下变量: api_key,session_key,call_id, sig,v,uids,fields, format

文档中有对这几个变量的解释,例如其中format为可选参数,指定返回数据的格式为php还是json。默认值为PHP;uids是指要查询的用户的uid;fields 是要查询的用戶的信息项(如姓名,生日等)。

简单地说,你只要向Manyou API服务器端 http://api.manyou.com/openapi.php 发送一个HTTP请求,以POST方式提交以上几个变量,即可得到相应的结果。 但提交变量时需要遵循一定格式,本文后面会举例说明。

如果你看了更多方法的文档,你会发现不论调用服务器端的哪一个方法,都必须向服务器端POST(不能用GET)以下几个参数:

  • method 要调用的服务器端方法
  • args 传递给服务器端方法的参数
  • api_key 当前应用的授权码
  • session_key 用户的sessionid
  • format 返回结果的格式,可以设置为php或json (默认值为php)
  • v API版本 默认为 0.1
  • sig signature(签名)。Manyou API服务器端以此判断客户端的请求是否合法。

下面一一介绍如何在客户端中设置这几个参数的值:

  • method

我们想调用user.getinfo方法, 那么method变量的值应为’user.getinfo’。

  • args 如果我们调用的方法需要提交参数(如uids),还需要向服务器端提交args变量。比如我想查uid为1042987的用户的信息,查询他的生日和年龄,则args变量的值为

$arg = array( ‘field’ =>array(‘birthday’,’age’), ‘uids’=> ‘1042987’ )

在实际使用时,应该把数组转变成字符串,方便传递。详见后文“sig的计算过程”。

  • api_key

这是开发者的App的授权码,应该在创建App时已经得到,在此设置即可;

  • session_key

由MYOP服务器通过POST或者GET方式发送到App(参见原理图)。 你只需要在App首页中读取一下MYOP服务器中发送过来的GET或POST数据中的my_sig_sessionId项,就可以得到这个值。

  • v API版本号,目前默认为’0.1’
  • sig 数字签名(signature) 计算过程略为复杂,见后文。
  • call_id

正确提交以上参数到Manyou API服务器端后,就可以得到相应的响应结果。

返回结果

MYOP服务器针对请求发回响应结果,其数据格式由format参数指定,可以是json形式,也可以是php序列化(serialize()函数)后的结果。如果是json形式,你需要将它转换为特定语言中的数据格式。例如利用json和对象的数据格式互换类库,可以把json对象直接转换为Java或PHP中的对象、数组等。

在返回的结果中,还包含errCode和errMessage两项信息,用于标识API调用时的出错情况。如果API调用成功,则errCode值为0。如果在调用时出错,errorCode和errorMessage会根据不同的API方法给出具体出错信息。请参考本Wiki中各个API方法的页面,查看其中关于errorCode的详细说明。

提示:得到数据之后,你可以把数据设置到用户的cookie中,这样在App的不同页面不用重复提交请求到服务器端,提高效率。对于Iframe模式的App来说,使用cookie更为方便。


可用的工具包

开发一个Manyou API客户端可能需要以下工具,这些工具都是现成的:

  • 一个http client,用于发送http请求;

如Java中的org.apache.commons.httpclient.HttpClient、.NET 中的HttpWebRequest等。

  • 一个json解析器。

http://www.json.org/ 上有针对各种语言的Json解析包下载。

Sig 的计算过程

Sig (signature,签名)的计算略为麻烦,下面一步步详细介绍:

1. 将method、session_key、api_key、format、v等几个变量组合成一个数组,键名为变量名,键值为变量的值。 例如:

array(5) { ["method"]=> string(12) "user.getinfo" ["session_key"]=> string(32) "4892c47f000fea2b94b3a4cf044595c8" ["api_key"]=> string(32) "c1126c578a09bba4f1cb615144d62e42" ["format"]=> string(3) "PHP" ["v"]=> string(3) "0.1" }

2. 将数组按键名重新排序(如api_key首字母为a,应该被排为数组第一个元素)。 得到以下数组:

array(5) { ["api_key"]=> string(32) "c1126c578a09bba4f1cb615144d62e42" ["format"]=> string(3) "PHP" ["method"]=> string(12) "user.getinfo" ["session_key"]=> string(32) "4892c47f000fea2b94b3a4cf044595c8" ["v"]=> string(3) "0.1" }

3.将数组中所有元素合并成一个字符串。格式为key1=value1&key2=value2&... 例如:

api_key=c1126c578a09bba4f1cb615144d62e42&format=PHP&method=user.getinfo&session_key=4892c324000fea2b42c1f8648f03ee3f&v=0.1&

4. 将以上字符串与方法参数字符串相连。 方法参数为args[argname]=argvalue形式,多个参数间用&相连,参数按首字母排列。如果某个参数为数组,则将数组元素用逗号相连。

如我们调用user.getinfo 时,需要使用uids和fields两个参数。则我们使用一个args参数数组,将uids参数与fields参数用&相连。按首字母,fields参数放在uids参数前。

同时,fields参数是一个数组:array(’name’,’sex’),我们将name和sex和逗号相连。

则整个字符串为:

api_key=c1126c578a09bba4f1cb615144d62e42&format=PHP&method=user.getinfo&session_key=4896c1f0000fea2ba38bc94ee52a06f6&v=0.1&args[fields]=name,sex&args[uids]=1042987&

5. 将以上字符串与App 密码(secret)相连

api_key=c1126c578a09bba4f1cb615144d62e42&format=PHP&method=user.getinfo&session_key=4892c419000fea2bcc9a978d4b3e5b0b&v=0.1&args[fields]=name&args[uids]=1042987&a87b32b473118cb1ec6262a9c31ab403

6. 将以上字符串进行MD5加密,得到

1e8c87ecc6208fc7c16096d1674d5fbf

这就是我们所要的最终的数字签名。

如果sig字符串计算有误,提交到服务器端后会返回“Incorrect signature”错误。

下面是PHP版本的计算过程,供参考:

注意:提交给服务器的参数分两类,一类是调用的API方法名称,session_key,api_key,要求返回的数据格式等,另一类是传递给要调用的API方法的参数。传递给API方法的参数要构造成args[argname]=argvalue形式的字符串,例如args[fields]=name,sex&args[uids]=1042987&

<?php $params = array(); $params['method'] = $method; $params['session_key'] = $this->session_key; $params['api_key'] = $this->api_key; $params['format'] = 'PHP'; $params['v'] = '0.1'; ksort($params); $str = ''; foreach ($params as $k=>$v) { $str .= $k . '=' . $v . '&'; } ksort($args); foreach ($args as $k=>$v) { if (is_array($v)) { $v = join(',', $v); } $params['args'][$k] = $v; $k = 'args[' . $k . ']'; $str .= $k .'=' . $v . '&'; } $params['sig'] = md5($str . $this->secret); ?>

参考代码

MYOP提供PHP版本的客户端代码,建议API Client开发者下载并参阅该客户端源代码。虽然语法不同,相信有一定帮助。 下载地址:PHP

PHP语言版本的客户端主要有两个类:

  • Manyou_API_Client类;
  • Manyou类

Manyou_API_Client类

主要负责与Manyou的REST风格的API进行交互,获得App必需的一些信息。

Manyou_API_Client中比较重要的有两个方法,是其它方法的基础: _call_method()和post_request()

post_request()使用CURL发送HTTP请求到Manyou的Web Service服务器,并取回结果。 _call_method()用于将类中的方法调用封装成符合Manyou Web Service要求的调用。

Manyou类

利用Manyou_API_Client从Manyou获取App需要的一些信息,并进行处理(如存入Cookie),便于App服务器使用。

具体实现请看源代码。

个人工具
接口文档