目录
1.前言
现在项目都采用前后端分离开发,所以后端的接口遵循RESTFUL风格很重要。RESTful只是一种架构方式的约束,给出一种约定的标准,完全严格遵守RESTful标准并不是很多,也没有必要。但是在实际运用中,有RESTful标准可以参考,是十分有必要的。
2.RESTFUL的来源
restful的全称为:Representational State Transfer,即为表现层状态转变。早期只需要get和post方法,post方法的出现只是消除get的url参数过长,上传一些文件。后来omcat 7 中的 servlet api 实现doOptions, doGet, doHead, doPost, doPut, doDelete,doTrace:
1.每一个URI代表一种资源;
2.客户端和服务器之间,传递这种资源的某种表现层;
3.客户端通过四个HTTP动词(get、post、put、delete),对服务器端资源进行操作,实现”表现层状态转化”。
3.patch和put的区别
patch用于更新某条字段的某一部分属性。put是更新一个比较完整的资源,比如一条数据的全部信息除了主键。
4.http的状态码
HTTP状态码也是有规律的,我们在设计接口的时候应该按照以下的状态码来设置。
1**请求未成功
2**请求成功、表示成功处理了请求的状态代码。
3**请求被重定向、表示要完成请求,需要进一步操作。 通常,这些状态代码用来重定向。
4** 请求错误这些状态代码表示请求可能出错,妨碍了服务器的处理。
5**(服务器错误)这些状态代码表示服务器在尝试处理请求时发生内部错误。 这些错误可能是服务器本身的错误,而不是请求出错。
5.url的命名规范
API 命名应该采用约定俗成的方式,保持简洁明了。在RESTful架构中,每个url代表一种资源所以url中不能有动词,只能有名词,并且名词中也应该使用复数。实现者应使用相应的Http动词GET、POST、PUT、PATCH、DELETE、HEAD来操作这些资源即可
不规范的的url,冗余没有意义,形式不固定,不同的开发者还需要了解文档才能调用。
https://example.com/api/getallUsers GET 获取所有用户
https://example.com/api/getuser/1 GET 获取标识为1用户信息
https://example.com/api/user/delete/1 GET/POST 删除标识为1用户信息
https://example.com/api/updateUser/1 POST 更新标识为1用户信息
https://example.com/api/User/add POST 添加新的用户
规范后的RESTful风格的url,形式固定,可读性强,根据users名词和http动词就可以操作这些资源
https://example.com/api/users GET 获取所有用户信息
https://example.com/api/users/1 GET 获取标识为1用户信息
https://example.com/api/users/1 DELETE 删除标识为1用户信息
https://example.com/api/users/1 Patch 更新标识为1用户部分信息,包含在body中
https://example.com/api/users POST 添加新的用户
6.统一的数据返回格式
统一的数据返回格式对于客户端的处理很方便,我们在设计response的时候可以设计一个common的返回体,比如:
public class CommonResponse<T> : IResponse
{
public CommonResponse()
{
Succeeded = true;
Logs = new List<string>();
ResponseCode = "200";
}
public bool Succeeded { get; set; }
public string ResponseCode { get; set; }
public string ErrorMessage { get; set; }
public string StackTrace { get; set; }
public T ResponseEntry { get; set; }
public List<T> ReponseEntryList { get; set; }
public int? TotalCount { set; get; }
public List<string> Logs { get; set; }
public void AddLog(string message, LogType logType = LogType.INFO)
{
Logs.Add($" [{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}]
[{logType.ToString()}] {message}");
}
}
这个common类就设置了一些共同的返回属性,比如succeeded,responsecode,errormsg等,实现返回一致性。
7.url多参数时的处理
这是一个比较头痛的问题,在做单个实体的查询比较容易和规范操作,但是在实际的API并不是这么简单而已,这其中常常会设计到多表连接、多条件筛选、排序等。
比如我想查询一个获取在6月份的订单中大于500元的且用户地址是北京,用户年龄在22岁到40岁、购买金额降序排列的订单列表
https://example.com/api/orders?order_month=6&order_amount_greater=500&address_city=北京&sort=order_amount_desc&age_min=22&age_max=40
从这个URL上看,参数众多、调用起来还得一个一个仔细对着,而且API本身非常不容易维护,命名看起来不是很容易,不能太长,也不能太随意。
在.net WebAPI总我们可以使用属性路由,属性路由就是讲路由附加到特定的控制器或操作方法上装饰Controll及其使用[Route]属性定义路由的方法称为属性路由。
这种好处就是可以精准地控制URL,而不是基于约定的路由,简直就是为这种多表查询量身定制似的的。 从webapi 2开发,现在是RESTful API开发中最推荐的路由类型。
我们可以在Controll中标记Route
[Route(“api/orders/{address}/{month}”)]
Action中的查询参数就只有金额、排序、年龄。减少了查询参数、API的可读性和可维护行增强了。