【服务计算】REST API学习与设计——模仿GithubAPI设计博客网站API

文章目录

  • 什么是REST?
  • 了解Web API
  • 学习Github-API
  • 设计博客网站API
    • 获取用户信息
    • 获得某用户所有文章总览
    • 访问用户的某一个指定的文章
    • 查看某用户关注信息
    • 获取用户下的分类专栏文章
    • 发布文章
    • 发布评论
    • 修改文章
    • 删除文章
  • 错误处理
    • 404 Not Found
    • 400 Bad Request
    • 401 Unauthorized

什么是REST?

REST:全称Representational State Transferer,是Roy Fielding博士在他的博士论文中提出来的一种软件架构风格。注意它是一种风格,而不是某个标准或者某个框架。但是根据这中定义的风格编写Web程序,就会得到一个比较优质的系统。
好,回到REST的理解上,将其名字翻译过来是“表示层状态转移”,很难理解。不妨试着在这个短语前加上一个名词,Resources,资源表示层状态转移,这样理解起来就要方便得多了。
资源表示层状态转移,首先对象是对资源,也就是网络上传输的数据包括各种格式的。那么表示,就是URL的表示方法,用url来表示一个资源。那么状态转移呢?对应的就是HTTP中的请求:GET、POST、PUT等,通过这些请求实现资源状态的改变,这就是REST干的事情。
用知乎上一个高赞回答(@Ivony)概括一下,就是“URL定位资源,用HTTP描述操作”。

了解Web API

参考资料:廖雪峰老师的网站
当我们访问某个URL的时候,往往得到的是一个完整的html页面,包括了数据以及其渲染的模式,这样呈现出来的信息可就复杂得多了,包括图片、表格等形式的信息。可是如果返回的信息是JSON格式?或者直接是二进制字符?这样机器就能够直接解析,那么这就是一个API。
可以看出API将数据或者说资源以URL的形式存到一个地方,进程或者机器通过一些方法取读取、修改这些数据,从而达到提供服务的目的。
看到这里,是不是发现跟上面的REST有点像呀?对了这就是为什么两者一拍即合,REST这种风格立刻就流行起来了。
API就是将Web的功能封装成一个个url的形式,通过API对数据进行操作,分离了前后端代码。

学习Github-API

参考资料:GithubAPI
可以看到开头就说明了这个使用了v3的REST API请求,建议通过Accept header来明确请求的版本。
通过查阅资料我们可以发现,有的REST API设计的时候建议在url中加上相应的版本好,这样的话确实能够十分明确告诉使用者使用的是什么版本,而且有着这个信息就可以不需要向后兼容,而且开放API对于多用户来讲十分难以管理版本问题,加上版本好就能很好的把问题交给用户自己处理。但是这样也造成一个混乱,多了许多版本的时候需要迁移代码,版本本来和资源本身没有关系,URL是表示资源的(前面提到),加入版本号就使得URL的意思更加复杂。相反加在Header中使得url表示更简洁一点。不同的使用方式,导致不同的设计模式的选择。
这次就模仿Github使用默认版本号的方式来设计。
Github所有API访问通过HTTPS来进行,所有数据通过JSON方式进行传输。可以包含空白字段,使用null来表示,不会将其省略,保证信息完整。
访问api.github.com得到以下信息:
【服务计算】REST API学习与设计——模仿GithubAPI设计博客网站API_第1张图片
可以看到通过访问不同的url可以获取不同的资源数据。
首先需要了解以下HTTP的各个操作:

GET
GET 从所给URL中获取资源以及资源的表示方式。

POST
POST 在所给的 URI 处创建的新资源。

PUT
PUT 在所给的 URI 中创建或替换资源。

PATCH
PATCH 对 URI 中资源执行部分更新。

DELETE
DELETE 删除位于指定 URI 处的资源。

设计博客网站API

https://api.blog.com为例:

获取用户信息

GET /users/:username

Response:
{
  "login": "octocat",
  "user_id": 1,
  "url": "https://api.blog.com/users/octocat",
  "html_url": "https://blog.com/octocat",
  "followers_url": "https://api.blog.com/users/octocat/followers",
  "following_url": "https://api.blog.com/users/octocat/following{/other_user}",
 
  "articles_url": "https://api.github.com/users/octocat/articles",
  
  "type": "User",
  "site_admin": false,
  "name": "octocat",
  "company": "",
  "location": "",
  "email": "[email protected]",
  "hireable": false,
  "followers": 20,
  "following": 0,
  "created_at": "2008-01-14T04:33:35Z",
  "updated_at": "2008-01-14T04:33:35Z"
}

获得某用户所有文章总览

GET /users/:userame/articles
Response:
{
	"count": 10,
	{
		"articleID": 1,
		"category": "learning",
		"category_id": "{id}",
		"title": "articleTitle",
		"article_url": "https://blog.com/:username/:article"
		"readings": 10,
		"word_count": 1024,
		"content": "contents...."
		"comment":[
			{
				"id": 1,
				"user": "username",
				"content": "xxx",
			},
			{
				...
			}
		],
		"created_at": "2008-01-14T04:33:35Z",
	    "updated_at": "2008-01-14T04:33:35Z",
	},
    {
     	"articleID"= 2,
     	....
    },
	...
}	 

访问用户的某一个指定的文章

GET /users/:username/articles/{article_id}
Response:
{
	"articleID": 1,
	"category": "learning",
	"category_id": "{id}",
	"title": "articleTitle",
	"article_url": "https://blog.com/:username/:article"
	"readings": 10,
	"word_count": 1024,
	"content": "contents...."
	"comment":[
		{
			"id": 1,
			"user": "username",
			"content": "xxx",
		},
		{
			...
		}
	],
	"created_at": "2008-01-14T04:33:35Z",
    "updated_at": "2008-01-14T04:33:35Z",
}

查看某用户关注信息

GET /users/:username/followers
Response:
{
	"user_id": 5,
	"url": "https://api.blog.com/users/:username",
	"html_url": "https://blog.com/:username",
	"created_at": "2008-01-14T04:33:35Z",
    "updated_at": "2008-01-14T04:33:35Z",
}

获取用户下的分类专栏文章

GET /users/:username/category
Response:
{
	"category": "learning",
	"category_id": "{id}",
	"count": 11,
	"articles": [
		{
			"articleID": 1,
			"category": "learning",
			"category_id": "{id}",
			"title": "articleTitle",
			"article_url": "https://blog.com/:username/:article"
			"readings": 10,
			"word_count": 1024,
			"content": "contents...."
			"comment":[
				{
					"id": 1,
					"user": "username",
					"content": "xxx",
				},
				{
					...
				},
			],
		}
	]
}

发布文章

POST /user/:username/article

获得Response包括自动生成文章ID,文章标题、分类等信息。

发布评论

POST /user/:username/articles/:ariticle_id/comment

以当前登录用户作为发起者,对某个文章发起评论。

修改文章

PUT /user/:username/article/:article_id

删除文章

DELETE /user/:username/article/:article_id

错误处理

HTTP错误状态码非常多,常用的就是以下几个

API 正常工作 (200, 201)
客户端错误 (400, 401, 403, 404)
服务端错误 (500, 503)

404 Not Found

404 Not Found
请求失败,请求所希望得到的资源未被在服务器上发现。通常在找不到资源时返回这个状态码。比如一些不存在的url,或者没有权限知道的,如私人权限的博客、未通过审核还没有成功发布的博客信息等。

400 Bad Request

由于包含语法错误,当前请求无法被服务器理解。通常在url后面会带有一些过滤信息(这里没有设计到),比如跳到某个小标题、指定分类条件之类的。又或者是用到POST、PUT等请求时,需要请求带有一定格式和必填字段,但是由于这些参数错误或者格式不全,就会导致请求不能被服务成功解析,返回400错误。

401 Unauthorized

当前请求需要用户验证。
通常在没有登录的状态下访问一些受保护的 API 时会用到这个状态码。

你可能感兴趣的:(服务计算)