到底什么是 REST/RESTful API?


=Start=

缘由:

一直都在听别人说什么REST/RESTful API的,之前也找过一些资料进行查看,但是看完了之后也是云里雾里的,没有什么比较明确、清晰的概念。最近又想了解一下这个概念了,所以又找资料看看,希望能有一个大致的概念,起码在和别人聊起来的时候不至于糊里糊涂的。

正文:

参考解答:

首先要明确一点:REST 实际上只是一种设计风格,它并不是标准。

  1. REST 是面向资源的,这个概念非常重要,而资源是通过 URI 进行暴露。
  2. REST很好地利用了HTTP本身就有的一些特征,如HTTP动词、HTTP状态码、HTTP报头等等。

用 URL 定位资源,用 HTTP动词(GET,POST,PUT,DELETE,..) 描述操作,用 HTTP状态码 表示操作结果。即:

  • 看 Url 就知道要什么;
  • 看 HTTP Method 就知道干什么;
  • 看 HTTP Status Code 就知道结果如何。
参考链接:

=END=

,

《“到底什么是 REST/RESTful API?”》 有 15 条评论

  1. 正确甄别API & REST API & RESTful API & Web Service之间的差异与联系
    https://juejin.im/post/5d07317e6fb9a07eac05d33c
    `
    1、API 与 REST API
    通俗的讲,API是一段应用程序与另一段应用程序相互“交流”的方式(协议)。
    REST是Representational State Transfer的缩写,直译过来就是:表述状态的转移。REST API是一组关于如何构建Web应用程序API的架构规则、标准或指导,或者说REST API是遵循API原则的一种架构风格。REST是专门针对Web应用程序而设计的,其目的在于降低开发的复杂度,提高系统的可伸缩性。

    2、REST API 与RESTful API
    3、REST与Web Service
    3-1、什么是Web Service?
    3-2、Web Service的优点
    3-3、Web Service的类型
    ​ 目前,Web Service主要有两大流派:
    1、基于SOAP的Web Service : SOAP(简单对象访问协议)是一种基于XML的协议,用以访问Web Service。其接口以机器可处理的格式进行描述,称为WSDL(Web服务定义语言)文档。通过使用标准的的XML文档来描述Web Service,在XML文件中,会详细记录接口的信息,如消息的格式、传输协议以及交互的位置等信息。
    2、基于REST的Web Service :REST(Representational State Transfer)是一种软件架构,它使用JSON来描述数据格式,最重要的是HTTP传输协议对REST来说是非必须的。

    3-4、REST与SOAP的区别和联系
    总结
    `

  2. RESTful API设计 最佳实践。
    https://blog.p2hp.com/archives/6437
    https://phauer.com/2015/restful-api-design-best-practices/
    `
    设计HTTP和RESTful API可能很棘手,因为没有官方和强制标准。基本上,有许多方法可以实现API,但其中一些已在实践中得到证实,并且已被widley采用。这篇文章介绍了构建HTTP和RESTful API的最佳实践。我们将讨论URL结构,HTTP方法,创建和更新资源,设计关系,有效负载格式,分页,版本控制等等。
    `

  3. 将token等认证信息放在URL参数中的危害及其缓解方法(Never Put Secrets in URLs and Query Parameters)
    https://www.fullcontact.com/blog/never-put-secrets-urls-query-parameters/
    `
    They get saved in browser history.
    They’re probably saved in your server’s logs and memory.
    Users might post the link, not realizing what they’ve shared.
    This information will be exposed in the “referrer” header.
    They’re available to browser extensions.

    漏洞场景:
    被保存在浏览器历史记录中
    被保存在服务器日志中
    无意识的敏感链接分享
    被保存在 referer 中
    可被浏览器扩展获取到
    可被搜索引擎检索到

    解决方案:
    将认证信息放在header中
    token过期时间设置
    一次性token
    敏感接口接入风控和二次认证
    `

  4. GraphQL正在超越REST
    https://mp.weixin.qq.com/s/ewL8B7ZqxkELpwT_FzTAaQ
    `
    # GraphQL的优点与挑战

    使用GraphQL的主要好处是,可以在单个请求中获得所需的全部内容,而使用REST,人们往往倾向于“过度获取”或“获取不足”。

    GraphQL简单,更快速,但是,当组合多个字段时,可能会遇到无法预测的性能问题。

    另一个挑战是版本控制。人们将不得不弃用一些字段,也无法知道字段是否随着时间发生了变化。

    GraphQL的另一缺点是缓存问题。在GraphQL中,不能将URL加入缓存标识符,这需要在应用程序中创建唯一键值来实现缓存。

    还有一部分额外的开销,因为服务器需要执行更多处理来解析查询与验证参数。

    最后,如果只是一些简单API的情况下,使用GraphQL增加额外复杂度并不值得。

    # 结论

    GraphQL类似于位于下游服务或数据源之前的API网关或代理服务器。就如同HTTP一样,可以使用动词来获得要求的内容。它也是REST,SOAP或gRPC的替代品,但这并不意味着必须替代当前的体系结构。比如,可以在REST服务之上安装GraphQL。

    GraphQL技术正变得越来越成熟,可用于多种语言,包括JavaScript,PHP,Python,Ruby,C#,Go,Scala或Java,而Pivotal等公司也大力倡导GraphQL。在实际应用中,它也是Spring IO 2019中提出的关键主题之一。
    `

  5. 开发安全的 API 所需要核对的清单
    https://github.com/shieldfy/API-Security-Checklist/blob/master/README-zh.md
    `
    以下是当你在设计, 测试以及发布你的 API 的时候所需要核对的重要安全措施.

    身份认证
    *  不要使用 Basic Auth 使用标准的认证协议 (如 JWT, OAuth).
    *  不要再造 Authentication, token generating, password storing 这些轮子, 使用标准的.
    *  在登录中使用 Max Retry 和自动封禁功能.
    *  加密所有的敏感数据.

    JWT (JSON Web Token)
    *  使用随机复杂的密钥 (JWT Secret) 以增加暴力破解的难度.
    *  不要在请求体中直接提取数据, 要对数据进行加密 (HS256 或 RS256).
    *  使 token 的过期时间尽量的短 (TTL, RTTL).
    *  不要在 JWT 的请求体中存放敏感数据, 它是可破解的.

    OAuth 授权或认证协议
    *  始终在后台验证 redirect_uri, 只允许白名单的 URL.
    *  每次交换令牌的时候不要加 token (不允许 response_type=token).
    *  使用 state 参数并填充随机的哈希数来防止跨站请求伪造(CSRF).
    *  对不同的应用分别定义默认的作用域和各自有效的作用域参数.

    访问
    *  限制流量来防止 DDoS 攻击和暴力攻击.
    *  在服务端使用 HTTPS 协议来防止 MITM 攻击.
    *  使用 HSTS 协议防止 SSLStrip 攻击.

    输入
    *  使用与操作相符的 HTTP 操作函数, GET (读取), POST (创建), PUT (替换/更新) 以及 DELETE (删除记录), 如果请求的方法不适用于请求的资源则返回 405 Method Not Allowed.
    *  在请求头中的 content-type 字段使用内容验证来只允许支持的格式 (如 application/xml, application/json 等等) 并在不满足条件的时候返回 406 Not Acceptable.
    *  验证 content-type 的发布数据和你收到的一样 (如 application/x-www-form-urlencoded, multipart/form-data, application/json 等等).
    *  验证用户输入来避免一些普通的易受攻击缺陷 (如 XSS, SQL-注入, 远程代码执行 等等).
    *  不要在 URL 中使用任何敏感的数据 (credentials, Passwords, security tokens, or API keys), 而是使用标准的认证请求头.
    *  使用一个 API Gateway 服务来启用缓存、访问速率限制 (如 Quota, Spike Arrest, Concurrent Rate Limit) 以及动态地部署 APIs resources.

    处理
    *  检查是否所有的终端都在身份认证之后, 以避免被破坏了的认证体系.
    *  避免使用特有的资源 id. 使用 /me/orders 替代 /user/654321/orders
    *  使用 UUID 代替自增长的 id.
    *  如果需要解析 XML 文件, 确保实体解析(entity parsing)是关闭的以避免 XXE 攻击.
    *  如果需要解析 XML 文件, 确保实体扩展(entity expansion)是关闭的以避免通过指数实体扩展攻击实现的 Billion Laughs/XML bomb.
    *  在文件上传中使用 CDN.
    *  如果需要处理大量的数据, 使用 Workers 和 Queues 来快速响应, 从而避免 HTTP 阻塞.
    *  不要忘了把 DEBUG 模式关掉.

    输出
    *  发送 X-Content-Type-Options: nosniff 头.
    *  发送 X-Frame-Options: deny 头.
    *  发送 Content-Security-Policy: default-src ‘none’ 头.
    *  删除指纹头 – X-Powered-By, Server, X-AspNet-Version 等等.
    *  在响应中强制使用 content-type, 如果你的类型是 application/json 那么你的 content-type 就是 application/json.
    *  不要返回敏感的数据, 如 credentials, Passwords, security tokens.
    *  在操作结束时返回恰当的状态码. (如 200 OK, 400 Bad Request, 401 Unauthorized, 405 Method Not Allowed 等等).

    持续集成和持续部署
    *  使用单元测试和集成测试来审计你的设计和实现.
    *  引入代码审查流程, 不要自行批准更改.
    *  在推送到生产环境之前确保服务的所有组件都用杀毒软件静态地扫描过, 包括第三方库和其它依赖.
    *  为部署设计一个回滚方案.

    也可以看看:
    * yosriady/api-development-tools – 用于构建RESTful HTTP+JSON API的有用资源集合。
    `
    https://github.com/yosriady/api-development-tools

  6. 由一次安全扫描引发的思考:如何保障 API 接口的安全性?
    https://mp.weixin.qq.com/s/HP5wOHrac1usqE1lbnJGBw
    `
    # 服务端
    1. HTTP 请求中的来源识别
    2. 数据加密
    3. 数据签名
    4. 时间戳
    5. AppID
    6. 参数整体加密
    7. 限流
    8. 黑名单

    # 客户端
    1. 压缩
    2. 混淆
    3. 加密
    `
    如何设计一个安全的对外接口
    https://my.oschina.net/OutOfMemory/blog/3131916
    总结一些网站加密和混淆技术
    https://mp.weixin.qq.com/s?__biz=MzIzNzA4NDk3Nw==&mid=2457739271&idx=1&sn=2ca3269df75d5f734f44d8ea0d26d7f7&scene=21#wechat_redirect

  7. 前端登录,这一篇就够了
    https://mp.weixin.qq.com/s?__biz=MzIxNTQ2NDExNA==&mid=100000675&idx=1&sn=0cae464adcc549b239c28199f675e6d1
    `
    登录是每个网站中都经常用到的一个功能,在页面上我们输入账号密码,敲一下回车键,就登录了,但这背后的登录原理你是否清楚呢?今天我们就来介绍几种常用的登录方式。
    * Cookie + Session 登录
    * Token 登录
    * SSO 单点登录
    * OAuth 第三方登录

    Cookie 是服务器端发送给客户端的一段特殊信息,这些信息以文本的方式存放在客户端,客户端每次向服务器端发送请求时都会带上这些特殊信息。客户端请求服务端,服务端会为这次请求开辟一块内存空间,这个便是 Session 对象。

    Token 是服务端生成的一串字符串,以作为客户端请求的一个令牌。当第一次登录后,服务器会生成一个 Token 并返回给客户端,客户端后续访问时,只需带上这个 Token 即可完成身份认证。(服务器端不需要存放 Token,所以不会对服务器端造成压力,即使是服务器集群,也不需要增加维护成本。最常见的 Token 生成方式是使用 JWT(Json Web Token),它是一种简洁的,自包含的方法用于通信双方之间以 JSON 对象的形式安全的传递信息。)

    单点登录指的是在公司内部搭建一个公共的认证中心,公司下的所有产品的登录都可以在认证中心里完成,一个产品在认证中心登录后,再去访问另一个产品,可以不用再次登录,即可获取登录状态。

    OAuth 第三方登录,简单易用,对用户和开发者都友好,但第三方平台很多,需要选择合适自己的第三方登录平台。
    `

  8. “一把梭:REST API 全用 POST”
    https://coolshell.cn/articles/22173.html
    `
    * 为什么要用不同的HTTP动词
    * Restful 复杂查询
    * 几个主要问题的回应
    ** 1)为什么API 要Restful,并符合规范?–一个共识
    ** 2)为什么“过早优化”不适用于API设计? –因为API是一种契约,一旦被使用上,就很难再变更了
    ** 3)POST 更安全吗?
    ** 4)全用 POST 可以节省时间减少沟通吗?
    ** 5)早点回家的正确姿势
    ** 6)工作而已,优雅不能当饭吃 –希望大家都能尊重自己从事的这个职业,成为真正的职业化的程序员,而不是一个码农!你的工作给你权力,而只有你的行为才会给你尊重

    API的幂等对于控制逻辑来说是一件很重要的事。所谓幂等,就是该API执行多次和执行一次的结果是完全一样的,没有副作用。
    * POST 用于新增加数据,比如,新增一个交易订单,这肯定不能是幂等的
    * DELETE 用于删除数据,一个数据删除多次和删除一次的结果是一样的,所以,是幂等的
    * PUT 用于全部数更新,所以,是幂等的。
    * PATCH用于局部更新,比如,更新某个字段 cnt = cnt+1,明显不可能是幂等操作。

    幂等这个特性对于远程调用是一件非常关键的事,就是说,远程调用有很多时候会因为网络原因导致调用timeout,对于timeout的请求,我们是无法知道服务端是否已经是收到请求并执行了,此时,我们不能贸然重试请求,对于不是幂等的调用来说,这会是灾难性的。比如像转帐这样的业务逻辑,转一次和转多次结果是不一样的,如果重新的话有可能就会多转了一次。所以,这个时候,如果你的API遵从了HTTP动词的规范,那么你写起程序来就可以明白在哪些动词下可以重试,而在哪些动词下不能重试。如果你把所有的API都用POST来表达的话,就完全失控了。

    除了幂等这样的控制逻辑之外,你可能还会有如下的这些控制逻辑的需求:
    * 缓存。通过CDN或是网关对API进行缓存,很显然,我们要在查询GET 操作上建议缓存。
    * 流控。你可以通过HTTP的动词进行更粒度的流控,比如:限制API的请用频率,在读操作上和写操作上应该是不一样的。
    * 路由。比如:写请求路由到写服务上,读请求路由到读服务上。
    * 权限。可以获得更细粒度的权限控制和审计。
    * 监控。因为不同的方法的API的性能都不一样,所以,可以区分做性能分析。
    * 压测。当你需要压力测试API时,如果没有动词的区分的话,我相信你的压力测试很难搞吧。
    * ……等等

    也许,你会说,我的业务太简单了,没有必要搞这么复杂。OK,没有问题,但是我觉得你最差的情况下,也是需要做到“读写分离”的,就是说,至少要有两个动词,GET 表示是读操作,POST表示是写操作。
    `

  9. 对接同事的接口,他定义的所有接口都是 post 请求,理由是 https 用 post 更安全
    https://www.v2ex.com/t/830030?p=1
    `
    之前习惯使用 restful api ,如果说 https 只有 post 请求是安全的话?那为啥还需要 get 、put 、delete ?我该如何反驳他。

    1# post 是最好的,我也全部用 post 。大环境用什么就用什么,早点搞完早点回家抱老婆。
    2# 吵赢了对你有什么好处?

    7# emmmmmm 这样子说 不知道你能不能接受
    1 1 楼说的` 早点搞完早点回家抱老婆`是对的
    2 2 楼说的是实话, 自我追求最好放到自己的项目里
    3 即便赢了 他的`restful` 可能你也会崩溃
    4 复杂系统大部分人的 restful 也是四不像

    10# 全用 post 的压测不得疯?你都不知道这接口到底有没有写操作

    36# 就事论事,如果没有确凿的证据说明全量 post 不好,那就按对方的来呗,为了反驳而反驳显得很奇怪,只能说知识储备量不够。与其问为什么全部 post 不好,不如问问为什么 get 和 post 分开用更好,对比一下哪一种重要性更高,更符合你的业务模式。

    47# https 是传输数据全加密的,除了请求的目标 IP ,中间设备是抓不到任何内容的,path 部分 body 体都一样,除非请求发起端被黑了,信任了中间人的证书,然后被中间人劫持。
    (题外话,所以不要在公司的加域电脑或者需要安装上网控制的内网上干私人的事,对于 IT 和老板你 https 了也是光屁股的)

    `

回复 hi 取消回复

您的电子邮箱地址不会被公开。 必填项已用*标注