(三) Input 和 Output 理论 - Build API For Your Company 系列
介绍
这一节主要是简单梳理一下在 HTTP
的世界中 Input、Output理论,特别是为了新手朋友(像我一样)。这些知识非常简单,简而言之,就是 HTTP Request
和 Response
这两个概念。
Request
一个简单的 HTTP 请求大家应该不会陌生吧:
GET /places?lat=40.7592&lon=-73.9846 HTTP/1.1
Host: api.example.com
客服端发送一个 GET 请求并且使用 HTTP 1.1 的协议,携带着需要的查询参数,指向 /places
这个URI(Uniform Resource Identifier), 服务器的主机名也被定义好了。这也是我们在上网中,浏览器(客户端)所处理的最基本的事务。
下面是一个稍微复杂的请求:
POST /places/1 HTTP/1.1
Host: api.example.com
Authorization: Basic Y2VpY2htYW5uQHNpbW9uaXMuY29tOnBhc3N3b3Jk
Content-Type: application/json
{ "user_id": 2 }
这里面并没有什么新鲜的东西,并且这些头信息在我们日常使用Web时已经司空见惯,不过我还是稍微解释一下:
Header Information | 说明 |
---|---|
POST /places/1 HTTP/1.1 | 发起一个POST请求,并指向 /places/1 |
Host: api.example.com | 表示提供服务的主机名 |
Content-Type: application/json | 希望被服务器当作JSON格式的信息使用 |
Authorization: Basic ... | 基本的认证Token |
HTTP 其实非常简单(但是很强大),你可以用你任何熟知的编程语言或者框架来快速实现一个 HTTP 客服端。
作为 PHP 程序员, 你或许听过或者使用过 Guzzle:
Guzzle is a PHP HTTP client that makes it easy to send HTTP requests and trivial to integrate with web services.
--- guzzlephp.org
使用 Guzzle 来快速实现一下上面的 POST 请求:
use Guzzle\Http\Client;
$headers = [
'Authorization' => 'Basic Y2VpY2htYW5uQHNpbW9uaXMuY29tOnBhc3N3b3Jk',
'Content-Type' => 'application/json',
];
$payload = [
'user_id' => 2
];
// 创建一个客户端请求
$client = new Client('http://api.example.com');
$req = $client->post('/places/1', $headers, json_encode($payload));
当然你可以用 Python
或者 Ruby
来快速制作一个 HTTP 请求,curl
也是一个不错的工具。
Response
和 HTTP Request 一样,HTTP Responses 也有着相似的格式:
HTTP/1.1 200 OK
Server: nginx
Host: api.example.com
Connection: close
X-Powered-By: PHP/5.5.15
Cache-Control: no-cache
Date: Sun, 26 Oct 2014 04:27:46 GMT
Content-Type: application/json; charset=UTF-8
[{"id":"e7bd6160-4cf2-11e4-b398-9380ce905f1c","userId":"e43f48e0-4cf2-11e4-9a09-75c59b58eb6d","content":"Id consequatur animi rerum sunt vero vel soluta accusantium minima sit molestiae nihil consequatur in nisi omnis labore.","imageList":null,"mainImage":null,"sourceBlogId":null,"bookId":"e7744bf0-4cf2-11e4-b425-797896315f23","createTime":"2014-10-06 00:52:32","repostsCount":0,"commentsCount":0,"favorCount":0}],"userList":[{"id":"e43f48e0-4cf2-11e4-9a09-75c59b58eb6d","nickname":"Ebba Wyman II","avatar":"IMG_Test.png"}],"sourceBlogList":[],"bookList":[{"id":"e7744bf0-4cf2-11e4-b425-797896315f23","volumNum":"2","userId":"e6f730e0-4cf2-11e4-9fd2-c545ee9bbdee","coverPortrait":"IMG_Test.png","updatedTime":"2014-10-06 08:51:27"}]
这是一个包含JSON数据的一个Response示例,简单的分析一下:
Header Information | 说明 |
---|---|
HTTP/1.1 200 OK | 目前而言,我们的请求很快乐的被服务器接受了,没有出现网络协议失败的问题,或者抛出异常 |
Server: nginx | 处理该请求的Web服务器的类型 |
X-Powered-By | 这里会显示你服务器的使用的 PHP 的版本号,但这是不安全的操作,你应该修改 php.ini 配置文件: expose_php = off |
Content-Type: application/json | 说明返回的数据类型 |
Cache-Control: no-cache | 缓存控制 |
Date: Sun, 26 Oct 2014 04:27:46 GMT | 生成响应时的时间戳 |
这些,就是API如何工作的一些主要的基础知识。
JSON And XML
现在应该所有的 API 都会支持 JSON 格式的数据输出, 除非这是一个金融服务的API或者开发者是一个 moron 才会继续输出 XML 格式的数据。XML 曾经辉煌过一段时间,为不同平台之间的集成提供了一个非常好的基础,但是他的很多弊端也导致了它注定要走向历史。对于大多数开发工作来说,JSON IS FINE
,或者如果你是一个Ruby开发者,你可能想输出 YAML 格式。
Response 的数据结构(数据格式)
怎么说呢,Response 的数据结构其实没有必须要遵循的一个标准,很难去评价这种格式的对与错,如果你使用过的框架或者语言比较多,你会发现很多机构和公司的API接口,并没有一致的数据结构。但是看看这些人是如何格式化输出的,你会对自己的API设计有一个更好的想法:
JSON API
A standard for building APIs in JSON.
是JSON API的目标,或许你可以使用这套标准来构建你的API响应的数据结构。
JSON API 文档: http://jsonapi.org/format/
论坛里面有人翻译了中文版:http://phphub.org/topics/179
不过有点不理解的是,这套标准为什么要用 posts
来表示单个资源,以及一个资源集合,这个有时候让人很费解?
Twitter-style
个人挺喜欢 Twitter 的数据返回格式,Ask for one user get one user :
{
"name": "Jobs Long",
"id": "12332874234"
}
Ask for a collection of things and get a collection of things :
[
{
"name": "Jobs Long",
"id": "12332874234"
},
{
"name": "Steven Jobs",
"id": "10002334"
},
]
优势:
- 最简化的信息输出
- 几乎可以被任何框架/工具理解
劣势:
-
没有命名空间来处理分页以及其他的meta数据信息;
很好奇Twitter是如何实现分页这些信息的返回的(暂时没时间看。。。)
Facebook-style
Facebook 的数据样式和 twitter有类似的地方,但是当请求一个数据集合的时候:
{
"data": [
{
"name": "Jobs Long",
"id": "12332874234"
},
{
"name": "Steven Jobs",
"id": "10002334"
},
]
}
优势:
- 在数据集合的返回中可以放置更多的分页信息和其他元数据;
- 拥有额外的命名空间的简洁响应格式
Github-style
看看Github 的数据响应格式:
$ curl -i https://api.github.com/users/octocat/orgs
响应结果:
HTTP/1.1 200 OK
Server: GitHub.com
Date: Sun, 26 Oct 2014 14:39:36 GMT
Content-Type: application/json; charset=utf-8
// omitted for brevity ...
{
"login": "JobsLong",
"id": 4585899,
"gravatar_id": "",
"url": "https://api.github.com/users/JobsLong",
// omitted for brevity ...
}
可以把 Github 的API技术文档当作一个参考,详细阅读一下文档是一个不错的选择。在这块内容并没有太多的个人看法,只是把一些大家熟知的公司的API技术文档的链接给摆在这里,大家如果有兴趣可以自己去多看看,个人经历尚浅,没办法对这块内容做一个比较详细的分析,可以留着以后更新。
NExT Articles
下一章的内容包括 Status Code
, 错误信息的返回,以及 POST MAN 的使用;
文章不错. :+1: