RESTful概述

一、来源


  • REST:Representational State Transfer (表象层状态转变)
    • 每一个URL代表一个资源
    • 客户端和服务器之间,传递这种资源的某个表现层
    • 客户端通过四个HTTP动词(get、post、put、delete),对服务器资源进行操作,实现“表现层状态转化”

二、六大原则


1. C-S架构
  • 数据的存储在Server端,Client端只需要使用就行。两端彻底分离的好处使Client端代码的可移植性变强,Server端的拓展性变强。两端单独开发,互不干扰
2. 无状态性
  • http请求本身就是无状态的,基于C-S架构,客户端的每一次请求带有充分的信息能够让服务端识别。请求所需的一些信息都包含在URL的查询参数、header、body,服务端能够根据请求的各种参数,无需保存客户端的状态,将响应正确返回给客户端。无状态的特征大大提高了服务端的健壮性和可扩展性
  • 无状态性也存在一点缺陷,客户端每次请求都必须带上相同重复的信息确定自己的身份和状态,造成传输数据的冗余性,但这种确定对于性能和使用来说,几乎可以忽略不计
3. 统一的接口
  • REST架构的核心是统一的接口。客户端只需要关注实现接口就可以,接口的可读性加强,使用人员方便调用
4. 一致的数据格式
  • 服务端返回的数据格式要么是xml,要么是json,或者直接返回状态码。
  • 每一项数据都应该具备自我描述的信息,方便代码处理和解析其中的内容。比如:通过http返回的数据里有[MIME type]信息,从这个信息可以知道数据的具体格式。
5. 系统分层
  • 客户端通常无法表明自己是直接还是间接与端服务器进行连接,分层是同样要考虑安全策略
6. 可缓存
  • 在万维网上,客户端可以缓存页面的响应内容。因此响应都应隐式或显式的定义为可缓存的,若不可缓存要避免客户端在多次请求后旧数据或脏数据来响应。管理得当的缓存会部分地或完全地除去客户端与服务端的交互,进一步改善性能和延展性。
7. 按需编码、可定制代码(可选)
  • 服务端可选择临时给客户端下发一些功能代码让客户端来执行,从而定制和扩展客户端的某些功能。比如服务端可以返回一些 Javascript 代码让客户端执行,去实现某些特定的功能。
    提示:REST架构中的设计准则中,只有按需编码为可选项。如果某个服务违反了其他任意一项准则,严格意思上不能称之为RESTful风格。

三、RESTful的7个最佳实践


1. 版本
  • 将版本直接放到URL中,简洁明了
        https://example.com/api/v1/
    
2. 参数命名规范
  • query parameter 采用驼峰或下划线都可以
        https://example.com/api/users/today_login  获取今天登录的用户
        https://example.com/api/users/today_login&sort=login_desc  获取今天登录的用户并以降序排列
    
3. 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 添加新的用户
    
4. 统一返回数据格式
  • 对于合法的请求应该统一返回数据格式,以json为例:
    • code:包含一个证书类型的HTTP相应的状态码
    • status:包含文本:“success”,"fail"或“error”。
      • 状态码在500-599为“fail”
      • 状态码在400-499为“error”
      • 其余均为“success”
    • message:当状态值为“fail”和“error”时有效,用于显示错误信息。参照国际化标准,他可以包含信息码或者编码。
    • data:包含响应的body。当状态值为“fail”和“error”时,data仅包含错误原因或异常名称、或者null也可以是
        成功返回的响应json格式
        {
            "code": 200,
            "message": "success",
            "data": {
                "username": "123456",
                "age": 16,
                "address": "Beijing"
            }
        }
        
        失败返回的响应json格式
        {
            "code": 401,
            "message": "error message",
            "data": null
        }
    
    • 下面这个ApiResult的泛型类是在项目中用到的,拓展性强,使用方便。返回值使用统一的 ApiResult 或 ApiResult错误返回使用ApiResult.Error进行返回;成功返回,要求使用ApiResult.Ok 进行返回。
          public class ApiResult: ApiResult
              {
                  public new static ApiResult<T> Error(string message)
                  {
                      return new ApiResult<T>
                      {
                          Code = 1,
                          Message = message,
                      };
                  }
                  [JsonProperty("data")]
                  public T Data { get; set; }
              }
              public class ApiResult
              {
                  public static ApiResult Error(string message)
                  {
                      return new ApiResult
                      {
                          Code = 1,
                          Message = message,
                      };
                  }
          
                  public static ApiResult<T> Ok<T>(T data)
                  {
                      return new ApiResult<T>()
                      {
                          Code = 0,
                          Message = "",
                          Data = data
                      };
                  }
                  /// <summary>
                  /// 0 是 正常 1 是有错误
                  /// </summary>
                  [JsonProperty("code")]
                  public int Code { get; set; }
                  [JsonProperty("msg")]
                  public string Message { get; set; }
          
                  [JsonIgnore]
                  public bool IsSuccess => Code == 0;
              }
      
      
5. http状态码
  • 根据http status code就可以知道删除、添加、修改等是否成功
    • 1** 请求未成功
    • 2** 请求成功、表示成功处理了请求的状态码
    • 3** 请求被重定向、表示要完成请求,需要进一步操作。通常,这些状态码用来重定向
    • 4** 请求错误这些状态代码出现错误,妨碍了服务器的处理
    • 5** 服务器错误,表示服务器在尝试处理请求时发生内部错误。这些错误可能是服务器本身出错,而不是请求出错
6. 合理使用query parameter
  • 在请求数据时,客户端经常对数据进行过滤和分页等要求,而这些参数推荐采用HTTP Query Parameter的方式实现
        比如设计一个最近登陆的所有用户
        https://example.com/api/users?recently_login_day=3
    
        搜索用户,并按照注册时间降序
        https://example.com/api/users?recently_login_day=3
    
        搜索用户,并按照注册时间升序、活跃度降序
        https://example.com/api/users?q=key&sort=create_title_asc,liveness_desc
    
    
7. 多表、多参数连接查询如何设计URL
  • 示例:
        查询一个获取在6月份的订单中大于500元的且用户地址是北京,用户年龄在22岁到40岁、购买金额降序排列的订单列表
        
        https://example.com/api/order?order_mouth=6&order_amount_greater=500&address_city=Beijing&sort=order_amount_desc&age_min=20&age_max=40
        
        可以优化为
        https://example.com/api/orders/beijing/6?order_amount_greater=500&sort=order_amount_desc&age_min=22&age_max=40
    
    
  • 再如博客园开放的Api获取个人博客随笔列表
        请求方式:GET 
        请求地址:https://api.cnblogs.com/api/blogs/{blogApp}/posts?pageIndex={pageIndex} 
        (ps:blogApp:博客名)
    
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值