api idea 开发rest_你设计的API够RESTful吗?

7a4350cf249da258d4abf3d8d182c4b7.gif

背景

很多团队都在构建API,并且声称自己团队创建的API都是足够的RESTful,今天我们简单聊下RESTful API相关的一些概念和设计实践。

定义

REST(Representational State Transfer) - 表述性状态转移

简单一句是就指:服务器发送表述用于描述资源的当前状态,客户端发送表述用于描述客服端希望资源拥有的状态。

REST 是一种架构风格。定义了分布式系统中,各个组件之间的交互方式。

Richardson成熟度模型

13725bcac9b9d2a7b66c6d7d8f7a5b4f.png

  • LEVEL 0, 只用HTTP作为传输通道,不会使用HTTP的任何额外机制。例如SOAP、 RPC

  • LEVEL 1,  引入资源的概念,使用不同的URI完成不同的功能。

GET /books?author=“john”Response:[{“id”:11, “Game of thrones”},{“id”:22, “Notre Dame de Paris”}]GET /orders?action=create&bookId=11&quantity=2Response:{“id”: 3,“book-id”: 11,“quantity”: 2}GET /orders/3/delete

  • LEVEL 2,  用不同的URI定位资源,用不同的HTTP方法操作资源-CRUD。

GET /books?author=“john”200 OK[{“id”:11, “Game of thrones”},{“id”:22, “Notre Dame de Paris”}]POST /orders{“bookId”: 11“quantity”: 2,}201 CREATEDLocation: /orders/3 {“id”: “3”“bookId”: 11“quantity”: 2}DELETE /orders/3

  • LEVEL 3 - HATEOAS, 在返回的Representation中包含了与该资源相关资源的链接, 降低客户端编程错误(大约90%的错误出现在为服务器构造正确URI的过程中), 减少无效的状态转换调用。

GET /books?author=“john”200 OK{“data”: {[{“id”:11, “Game of thrones”},{“id”:22, “Notre Dame de Paris”}]},“links”: {“self”: “/books?author=john”“order”: “/orders”}}POST /orders{“bookId”: 11“quantity”: 2,}201 CREATEDLocation: /orders/3 {“data”:{“id”: “3”“bookId”: 11“quantity”: 2},“links”: {“self”: “/orders/3”,“payment”: “/payments?discount=95”}}DELETE /orders/3

对照以上的成熟度模型,我们可以比较明确的知道我们自己的API,属于哪个LEVEL?

API规范

无状态原则

服务端必须是没有状态的,换句话说,客户端的所有请求必须包括服务端完成请求的所有信息(e.g: 认证信息,表单数据);客户端不能假设服务端有任何的状态信息,所有的状态信息只有两种方式保持:

  • 资源状态

  • 客户端保存

服务无状态,很好的方便了水平扩展,高可用。

幂等原则

一次和多次请求某一个资源应该具有相同的副作用

幂等的方法意味着请求成功执行所得到的结果不依赖于该方法被执行的次数;这在分布式事务-特别是最终一致性的时候,我们都需要保证业务服务的幂等性息息相关。

在常见的HTTP Verbs里面,GET是天然的满足幂等性,为缓存提供了条件;DELETE和PUT/PATCH都可以实现幂等。

可缓存原则

在请求和响应的过程中,任何一个节点都可能会”缓存“响应数据, 因此响应都会显式或者隐式的包含”能否被缓存“的信息, 客服端和中间涉及的节点会根据这些信息,来进行后续处理。
比如:服务端可以使用Cache-Control等Http Header字段来控制缓存的期限,良好的缓存策略可以减少客户端-服务端的交互,降低服务端的负载,从而提供性能和可扩展性。

HTTP/1.1 200 OKDate: Fri, 26 Mar 2018 09:33:49 GMTCache-Control: max-age=3600 Last-Modified: Fri, 26 Mar 2018 09:33:49 GMT ETag: cde893c4

安全原则

在做API设计的的时候,以下是在实际开发中常遇到的安全问题:

  • 缺失了对资源从属关系的检查,对于URL中只出现一个资源的情况,绝大多数开发者都会知道做安全防御,然而,问题往往出现在包括多个资源的时候,e.g:/users/1/orders/239843,应用只检查了当前请求发起者是否是编号 为1的用户,以及编号为239843的订单是否存在,有很大的概率没有检查URL中的订单和用户之间的从属关系

  • HTTP响应中缺失必要的Security Header, 请合理使用以下的Header,可使得你开发的API具备更高的安全性。

    • X-XSS-Protection

    • Strict-Transport-Security

    • X-Content-Type-Options

    • X-Frame-Options

  • 泄露业务信息,在返回体中,不要暴露多余的信息,特别是铭感信息。

  • API缺乏速率限制的保护

兼容性原则
  • 当API出现较大升级并且包含破坏性改动的时候,服务提供者需要提供新的API版本,与此同时,需要保持对老版本API的支持,直到达到弃用的标准。

    • 常将API版本放在URL中,比如/v2/users/{uid};

    • 或者放在http header中, Accept: application/vnd.api+json;version=2

  • 在更改已有API的时候,不能更改字段的含义,只添加可选字段,不添加必选字段,当资源URL发生变化的时候,支持重定向。

API设计

API的设计遵循上面的四个原则,同时需要根据业务定义资源,用URI定位资源,并用HTTP verb来操作资源。

定义Resource

一切可以被命名的信息都可以叫做资源(Resource),资源是名词,不要是动词,e.g: 一个用户关注了另一个用户,这个资源应该被定义成“关系(relationship)”,而不是“关注(follow)”。

用URI定位资源
GET /users/{id}POST /usersPUT/PATCH /users/{id}DELETE /users/{id}

在我们团队中,定义了设计URL的军规

  • 使用复数,不管它代表的是一个资源还是一个资源集合 GET /users/123/orders/345

  • 使用“-”,分离多个单词,而不是驼峰, e.g: GET /users/{id}/account-type

JSON-API

最后,开发API的过程中,会花很多时间去和API的消费者沟通API接口的具体格式。例如Content-Type,JSON的字段的定义等等,需要耗费大量的精力,如果遵循共同的约定,可以提高开发效率,利用更普遍的工具,使开发者更加专注于开发重点,这里向大家推荐:JSON API Specification: http://jsonapi.org

  • meta:辅助信息

  • data:主体信息

  • attributes:资源的数据

  • errors:错误

  • links:链接

GET /users/123{”meta”: {…},“data”: {“type”: “user”,“id”: “123”,“attributes”: {},“relationships”: {},},“errors”: [],“links”: {…},“included”: {…}}

5c08adf2ca78f80d481da18311a80354.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
课程简介这是一门使用Java语言,SpringBoot框架,从0开发一个RESTful API应用,接近企业级的项目(我的云音乐),课程包含了基础内容,高级内容,项目封装,项目重构等知识,99%代码为手写;因为这是项目课程;所以不会深入到源码讲解某个知识点,以及原理,但会粗略的讲解下基础原理;主要是讲解如何使用系统功能,流行的第三方框架,第三方服务,完成接近企业级项目,目的是让大家,学到真正的企业级项目开发技术。适用人群刚刚毕业的学生想提高职场竞争力想学从零开发SpringBoot项目想提升SpringBoot项目开发技术想学习SpringBoot项目架构技术想学习企业级项目开发技术就是想学习SpringBoot开发能学到什么从0开发一个类似企业级项目学会能做出市面上90%通用API快速增加1到2年实际开发经验刚毕业学完后能找到满意的工作已经工作学完后最高涨薪30%课程信息全课程目前是82章,155小时,每节视频都经过精心剪辑。在线学习分辨率最高1080P课程知识点1~11章:学习方法,项目架构,编码规范,Postman使用方法,Git和Github版本控制12~16章:搭建开发环境,快速入门SpringBoot框架17~20章:快速入门MySQL数据库21~30章:MyBatis,登录注册,找回密码,发送短信,发送邮件,企业级接口配置31~41章:实现歌单,歌单标签,音乐,列表分页,视频,评论,好友功能42~48章:阿里云OSS,话题,MyBatis-plus,应用监控49~53章:Redis使用,集成Redis,SpringCache,HTTP缓存54~58章:Elasticsearch使用,集成Elasticsearch,使用ES搜索59~61章:商城,集成支付宝SDK,支付宝支付62~64章:常用哈希和加密算法,接口加密和签名65~67章:实时挤掉用户,企业级项目测试环境,企业级接口文档68~69章:SpringBoot全站HTTPS,自签证书,申请免费证书70~73章:云MySQL数据库,云Redis数据库使用,轻量级应用部署环境,域名解析74~80章:Docker使用,生产级Kubernetes集群,域名解析,集群全站HTTPS81~82章:增强和重构项目,课程总结,后续学习计划
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值