免费api设计(api 免费)

网友投稿 322 2023-01-22

本篇文章给大家谈谈免费api设计,以及api 免费对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。 今天给各位分享免费api设计的知识,其中也会对api 免费进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!

本文目录一览:

RESTful API 设计约定

本文编写目的是为了尽可能的约定好一个公司的产品、组件、项目开发的RESTful API 设计风格,使不同团队间设计的API风格尽量一致,减少项目后期由于规范问题或设计不足导致的接口重构造成的开发、测试返工。最终让接口的最终使用者能够在开发过程中有个良好的体验。

此约定可作为开发人员设计RESTful 接口或项目接口发布评审的参考。

个人观点:用了 JSON-RPC 不等于 是RESTful API ,RESTful API通常是基于HTTP/JSON方式实现的 ,两种方式的API设计方式都不错,项目中选适合的就好。简单对比如下:

本文仅是作者个人根据主观喜好和接口设计经验搜罗总结而来的RESTful API设计约定,仅作为接口设计的基本要求,也欢迎与大家讨论。此约定未涉及超文本HATEOAS相关内容,也不包含RPC类面向后端服务方法映射接口的范畴。

API 是后端应用程序的脸面(UI),用户体验非常重要。尤其是当你开发的是一个可复用的组件或产品,如果API设计有些许瑕疵,会直接影响开发者的体验,设计者会被骂的…… 有问题的API一旦开放出去了,哪怕是简单的拼写错误,由于要保持兼容性不能删改,会成为技术欠债长期背下去。

以上关键点不只适用于RESTful API,其他类型API也是一样的。

作为对外公开发布的RESTful API,根URL中一般要有域名与版本信息。通常一个WEB站点会同时提供网站服务和API服务,我们需要根据URL能够区分出访问的是服务接口还是网站中的网页、文件等资源。因此RESTful API的根URL中根据不同场景一般会在一级域名中或者是子域名中带api关键字。

常见的两种根URL用法如下:

推荐的方案是根URL中采用子域名的方式区分API,即: https://iam.primeton.com/api/v1/*

路径终点即粗体部分内容: https:// example.org/api/v1/ menus

设计RESTful API时常用的HTTP Method包括:GET、POST、PUT、PATCH、DELETE 简单说明如下:

根据资源标识可以 唯一定位一个资源 时,建议使用URL路径参数方式传递。对应Springboot 的 @PathVariable 。API Path示例如下:

根据资源属性查询过滤 一或多个资源 时,建议使用URL查询参数方式传递。对应Springboot的 @RequestParam 。API Path示例如下:

对于简单查询类接口,可以使用路径参数和查询参数解决,如果是复杂功能型查询接口中需要通过复杂的过滤条件查询时如: < in between 等等,查询参数用起来会非常痛苦,GET Method又不支持提交Request Body参数。因此我建议这种 复杂型查询采用POST Method 提交到一个特定的Path上 。参见如下场景:

查询接口返回多个数据时,需要支持分页(枚举类数据或少量数据除外)和排序。

如需使用分页查询和排序,建议统一请求与响应报文结构,格式如下:

请求参数示例:

GET /users?page=1size=5sort=username

单页数据响应结果示例:

上述分页排序与响应报文格式是来自Spring Data定义的模型,为了保持分页排序接口相关的使用习惯,如果持久化不使用JPA,仍然建议采用上述规范的报文定义封装接口。为使用者提供一致的体验。

如果资源需要做一些增删改之外的操作(如状态变更),可以用 /actions 作为path

例如:流程平台中的流程实例会有状态变化,如启动、挂起、恢复、终止等等,这种接口建议这样设计:

组合资源,即两种资源之间存在组合关系,组合指整体与部分的强包含关系,但整体与部分是不可分的,整体的生命周期结束也就意味着部分的生命周期结束。对"部分"的操作一定会由整体作为入口,不会直接跳过"整体"来对"部分"做增删改查。这种组合场景中,推荐API设计方式示例如下:

聚合资源,即两种资源之间存在聚合关系。聚合也是整体与部分的弱包含关系,但整体与部分之间是可分离的,他们可以具有各自的生命周期,部分可以属于多个不同的主体对象,也可以为多个整体对象共享。

例如,机构或角色下包含人员,需要获取机构或角色下的人员的场景,避免做成分别通过机构入口或角色入口找人等重复的具有类似功能的接口:

在RESTful API设计中,正常和异常情况建议通过HTTP约定的status进行区分, 不建议 采用所有接口均POST Method调用,永远返回200这种模式。

推荐的常用Http Status说明如下:

HTTP 1.0 Status 详细说明参考

API调用成功后,返回HTTP 2xx状态码,Response Body直接返回业务数据即可。请求和响应报文建议统一采用JSON格式。

RESTful API 对于异常报文需要规范和统一,服务端出现异常情况下,需要进行全局拦截,然后将异常信息封装为规范的格式,返回给调用端。

对于后端的异常信息,建议包含编码和消息

本文是基于学习各路大神们对RESTful 设计相关文章,结合自己设计接口时遇到困惑后的解决方案,收集与总结而成的RESTful API设计约定。部分内容夹杂个人喜好与主观观点,抛砖引玉,希望能为大家设计API带来些许帮助。后如果遇到一些更复杂的场景,欢迎一起沟通。

RESTful api接口安全优雅设计

-- 陈万洲

在项目中,需要为APP撰写API。刚开始接触的时候,并没有考虑太多,就想提供URL,APP端通过该URL进行查询、创建、更新等操作即可。但再对相关规范进行了解后,才发现,API的设计并没有那么简单,远远不是URL的问题,而是一个通信协议的整体架构

请求模式也可以说是动作、数据传输方式,通常免费api设计我们在web中的form有GET、POST两种,而在HTTP中,存在下发这几种。

常见的请求参数

比如在数据过多, 需要对数据进行分页请求的时候, 我们应该统一 API 请求参数. 常见的有这些.

API的开发直接关系了APP是否可以正常使用,如果原本运行正常的API,突然改动,那么之前使用这个API的APP可能无法正常运行。APP是不可能强迫用户主动升级的,因此,通过API版本来解决这个问题。也就是说,API的多个版本是同时运行的,而且都要保证可以正常使用。

按照RESTful的规范,不同的版本也应该用相同的API URL,通过header信息来判断版本,再调用不同版本的程序进行处理。但是这明显会给开发带来巨大的成本。

解决办法有以下几种:

接口的数据一般都采用JSON格式进行传输,不过,需要注意的是,JSON的值只有六种数据类型:

所以,传输的数据类型不能超过这六种数据类型。以前,我们曾经试过传输Date类型,它会转为类似于"2016年1月7日 09时17分42秒 GMT+08:00"这样的字符串,这在转换时会产生问题,不同的解析库解析方式可能不同,有的可能会转乱,有的可能直接异常了。要避免出错,必须做特殊处理,自己手动去做解析。为了根除这种问题,最好的解决方案是用毫秒数或者字符串表示日期。

服务器返回的数据结构,一般为:

不同错误需要定义不同的返回码,属于客户端的错误和服务端的错误也要区分,比如1XX表示客户端的错误,2XX表示服务端的错误。这里举几个例子:

错误信息一般有两种用途:一是客户端开发人员调试时看具体是什么错误;二是作为App错误提示直接展示给用户看。主要还是作为App错误提示,直接展示给用户看的。所以,大部分都是简短的提示信息。

data字段只在请求成功时才会有数据返回的。数据类型限定为对象或数组,当请求需要的数据为单个对象时则传回对象,当请求需要的数据是列表时,则为某个对象的数组。这里需要注意的就是,不要将data传入字符串或数字,即使请求需要的数据只有一个,比如token,那返回的data应该为:

首先,使用https可以在数据包被抓取时多一层加密。我们现在的APP使用环境大部分都是在路由器WIFI环境下,一旦路由器被入侵,那么黑客可以非常容易的抓取到用户通过路由器传输的数据,如果使用http未经加密,那么黑客可以很轻松的获取用户的信息,甚至是账户信息。

其次,即使使用https,也要在API数据传输设计时,正确的采用加密。例如直接将token信息放在URL中的做法,即使免费api设计你使用了https,黑客抓不到免费api设计你具体传输的数据,但是可以抓到你请求的URL啊免费api设计!(查了资料了,https用GET方式请求,也仅能抓到域名字符部分,不能抓到请求的数据,但是URL可以在浏览器或特殊客户端工具中直接看到。多谢下面的朋友指正错误)因此,使用https进行请求时,要采用POST、PUT或者HEAD的方式传输必要的数据。

现在,大部分App的接口都采用RESTful架构,RESTFul最重要的一个设计原则就是,客户端与服务器的交互在请求之间是无状态的,也就是说,当涉及到用户状态时,每次请求都要带上身份验证信息。实现上,大部分都采用token的认证方式,一般流程是:

然而,此种验证方式存在一个安全性问题:当登录接口被劫持时,黑客就获取到了用户密码和token,后续则可以对该用户做任何事情了。用户只有修改密码才能夺回控制权。

如何优化呢免费api设计?第一种解决方案是采用HTTPS。HTTPS在HTTP的基础上添加了SSL安全协议,自动对数据进行了压缩加密,在一定程序可以防止监听、防止劫持、防止重发,安全性可以提高很多。不过,SSL也不是绝对安全的,也存在被劫持的可能。另外,服务器对HTTPS的配置相对有点复杂,还需要到CA申请证书,而且一般还是收费的。而且,HTTPS效率也比较低。一般,只有安全要求比较高的系统才会采用HTTPS,比如银行。而大部分对安全要求没那么高的App还是采用HTTP的方式。

我们也给每个端分配一个appKey,比如Android、iOS、微信三端,每个端分别分配一个appKey和一个密钥。没有传appKey的请求将报错,传错了appKey的请求也将报错。这样,安全性方面又加多了一层防御,同时也方便对不同端做一些不同的处理策略。

另外,现在越来越多App取消了密码登录,而采用手机号+短信验证码的登录方式,我在当前的项目中也采用了这种登录方式。这种登录方式有几种好处:

不需要注册,不需要修改密码,也不需要因为忘记密码而重置密码的操作了;

用户不再需要记住密码了,也不怕密码泄露的问题了;

相对于密码登录其安全性明显提高了。

显式用户和隐式用户,我不知道这两个词用的是否确切。 

显式用户指的是,APP程序中有用户系统,一个username、password正确的合法用户,称之为显式的用户,

通常显式用户都需要注册,登录以后能完成一些个人相关的操作。

隐式用户指的是,APP程序本身就没有用户系统,或者一个在没有登录的情况下,使用我们APP的用户。

在这种情况下,可以通过客户端生成的UDID来标识一个用户。

有了用户信息,我们就能够了解不同用户的使用习惯,而不仅仅是全体用户的一个整体的统计信息,

有了这些个体的信息之后,就可以做一些用户分群、个性化推荐之类的事情。

如果是SAAS版本,还需要区分不同商户的用户

接口文档有时候是项目初期就定下来的,前后端开发人员按照接口规范开发,

有的是接口开发完成后写的。

接口文档要清晰、明了,包含多少个接口,每个接口的地址、参数、请求方式、数据交换格式、返回值等都要写清楚。

接口测试程序,有条件的话,也可以提供,方便前后端的调试。

如果是springMVC开发的话,可以用swagger,后端只要加几个注释发一个url给前端就可以了,轻松又高效。

在做PC端网站的时候,我们都会给我们的网站加上个统计功能,要么自己写统计系统,要么使用第三方的比如GA、百度等。

移动端接口API则需要我们自己实现统计功能,

这时就需要我们尽可能多的收集客户端的信息,除了传统的IP、User-Agent之外,还应该收集一些移动相关的信息,

比如

手机操作系统,是android还是ios,都是什么版本,

用户使用的网络状况,是2G、3G、4G还是WIFI

客户端APP是什么版本信息。

这样,有助于我们更好的了解我们用户的使用情况。

如何设计好的RESTful API

安全是恒久的话题,对于基于WSDL和SOAP的Web Service,我们有WS-Security这样的安全规范来指导实现认证、授权、身份管理等安全需求。那么,RESTful API有无成熟可用规范或实现框架呢?如何保证RESTful API的安全性呢?
如何对RESTful API进行版本控制,请分享您认为实用的做法?
HTTP1.1规范中给出的动词对于设计RESTful API够用吗?您在实际项目中会扩展自己的动词吗?在什么情况下需要扩展?
今年5月份发布的JAX-RS 2.0规范对于RSTfulAPI的设计最有价值的特性是哪个(些)? 它(们)用于解决什么问题?
能否为InfoQ的读者们推荐一款实用的RESTful API开发框架,并说明您的推介理由。
HTTP2.0规范正在制定当中,您对它的期待是什么?
InfoQ:什么是好的RESTful API?相信每个人都有自己的评判标准。那么,您认为一个好的RESTful API应该具有哪些特征呢?

李锟:一个好的RESTful API,应该具备以下特征:
这个API应该是对浏览器友好的,能够很好地融入Web,而不是与Web格格不入。
浏览器是最常见和最通用的REST客户端。好的RESTful API应该能够使用浏览器+HTML完成所有的测试(不需要使用编程语言)。这样的API还可以很方便地使用各种自动化的Web功能测试、性能测试工具来做测试。Web前端应用(基于浏览器的RIA应用、移动App等等)也可以很方便地将多个RESTful API的功能组合起来,建造Mashup类的应用。
这个API中所包含的资源和对于资源的操作,应该是直观和容易理解的,并且符合HTTP协议的要求。
REST开发又被称作“面向资源的开发”,这说明对于资源的抽象,是设计RESTful API的核心内容。RESTful API建模的过程与面向对象建模类似,是以名词为核心的。这些名词就是资源,任何可命名的抽象概念都可以定义为一个资源。而HTTP协议并不是一种传输协议,它实际提供了一个操作资源的统一接口。对于资源的任何操作,都应该映射到HTTP的几个有限的方法(常用的有GET/POST/PUT/DELETE四个方法,还有不常用的PATCH/HEAD/OPTIONS方法)上面。所以RESTful API建模的过程,可以看作是具有统一接口约束的面向对象建模过程。
按照HTTP协议的规定,GET方法是安全且幂等的,POST方法是既不安全也不幂等的(可以用来作为所有写操作的通配方法),PUT、DELETE方法都是不安全但幂等的。将对资源的操作合理映射到这四个方法上面,既不过度使用某个方法(例如过度使用GET方法或POST方法),也不添加过多的操作以至于HTTP的四个方法不够用。
如果发现资源上的操作过多,以至于HTTP的方法不够用,应该考虑设计出更多的资源。设计出更多资源(以及相应的URI)对于RESTful API来说并没有什么害处。
这个API应该是松耦合的。
RESTful API的设计包括了三个循序渐进、由低到高的层次:资源抽象、统一接口、超文本驱动。正是这三个层次确保了RESTful API的松耦合性。
当设计面向互联网的API时,松耦合变成了一种“必须有”的强需求。紧耦合的API非常脆弱,一旦公布出去,服务器端和客户端都无法持续进化。尤其是服务器端,公布出去的接口根本不敢改,改了之后,几乎所有客户端应用立即无法正常工作。REST这种架构风格就是紧耦合API的解毒剂,这个话题可以谈的很深,这里就不展开了。感兴趣的读者可以参考《REST实战》。
这个API中所使用的表述格式应该是常见的通用格式
在RESTful API中,对于资源的操作,是通过在服务器端-客户端之间传递资源的表述来间接完成的。资源的表述可以有很多种格式,并且在响应和请求中的资源表述格式也会有所不同。GET/POST响应中的资源表述格式,常见的有HTML、XML、JSON;POST/PUT请求中的资源表述格式,常见的有标准的HTML表单参数、XML、JSON。
这些常见表述格式,处理起来非常容易,有大量的框架和库提供支持。所以除非有很合理的要求,通常不需要使用自定义的私有格式。
使用HTTP响应状态代码来表达各种出错情况
HTTP响应状态代码,是HTTP协议这个统一接口中用来表达出错情况的标准机制。响应状态代码分成两部分:status code和reason phase。两部分都是可定制的,也可以使用标准的status code,只定制reason phase。
如果一个所谓的“RESTful API”对于任何请求都返回200 OK响应,在响应的消息体中返回出错情况信息,这种做法显然不符合“确保操作语义的可见性”这个REST架构风格的基本要求。
这个API应该对于HTTP缓存是友好的
充分利用好HTTP缓存是RESTful API可伸缩性的根本。HTTP协议是一个分层的架构,从两端的user agent到origin server之间,可以插入很多中间组件。而在整个HTTP通信链条的很多位置,都可以设置缓存。HTTP协议内建有很好的缓存机制,可以分成过期模型和验证模型两套缓存机制。如果API设计者完全没有考虑过如何利用HTTP缓存,那么这个API的可伸缩性会有很多问题。
李建业:首先说明一下,对REST这个概念,我一般把它理解为REST风格的架构,但是现在实践中最为广泛认知的是HTTP,而它是REST的一个实现,所以RESTful API也可以不太严格的指基于HTTP的API——当然,即使是不严格的时候,API本身也应该力求遵循REST架构风格。
我认为,一个RESTful API最重要的一点应该是——“尽可能少的先验信息”,这一条也同时是我判断一个好的RESTful API的标准。
比如HTTP动词,在实践中,大家可能会常常纠结于有效利用 HTTP 动词,但这却并不是特别重要的事情——除非你理解这么做的价值。HTTP 动词最重要的地方在于它是标准阐明了的行为,也就是说,如果我们的“客户端”遵循约定,那么就不必要发明新的动词,也就不必增加“先验信息”;但是,所谓“先验信息”,针对的是客户端——对API来说就是调用者,对于一些企业内部系统,或者一些传统系统,由于“资源”很稳定,对资源的操作也很稳定,这些系统的“调用客户端”不是浏览器而是另一个系统,此时如果强制对应到HTTP动词,反而会变成额外的“先验信息”,这时我就不会太拘泥HTTP动词,自己制定一套动词放在参数中也可以接受——只要动词不变化,这个系统依然是REST风格的。
再比如Response里面的Content-Type,这个有时会被新手忽略,但这其实很重要,因为一般涉及到系统间协同的API,往往不会使用普通的文本,比较常见的是使用json表达复杂结构,而这与通常的缺省理解不同(缺省一般会认为是text/plain和text/html),所以如果在API中忘记用Content-Type进行区分的话,后续对多种类型的客户端接入的支持就会变成陷阱(我们多次遇到过这个问题)。而如果一开始就检查是否增加先验知识(缺省Content-Type为plain或者允许指定Content-Type),那这一困难就可以避免了。
丁雪丰:首先,应该正确地使用HTTP的统一接口,比如HTTP的动词,如果不分青红皂白清一色POST那显然还有改进的余地;
其次,资源有合适的粒度,可以从三个方面来评判资源的粒度是否合理——网络的效率、表述的大小以及客户端使用时的易用程度;
最后,是表述的设计,除了表述的正文内容,还有其中的URI和链接,这些都是评判一个RESTful API好坏的标准。
马钧:在我看来,一个好的API标准,就是能尽量利用到HTTP协议的特性,将HTTP当成一种转移协议,而不是传输协议。包括但不限于:利用HTTP的各种动词来明确操作;包含有内容协商,可以根据请求头提供的参数选择一个资源最合适的媒体类型、语言、字符集和编码的表现;使用不同的返回代码来描述各种状态。但实际上见到过的很多声称RESTful API,包括国内的和国外的,能符合这些条件的并不多。parse.com提供的API是我见到过的较为不错的RESTful API,可以作为范例参考。
InfoQ:安全是恒久的话题,对于基于WSDL和SOAP的Web Service,我们有WS-Security这样的安全规范来指导实现认证、授权、身份管理等安全需求。那么,RESTful API有无成熟可用规范或实现框架呢?如何保证RESTful API的安全性呢?
李锟:保证RESTful API的安全性,主要包括三大方面:
a) 对客户端做身份认证
b) 对敏感的数据做加密,并且防止篡改
c) 身份认证之后的授权
对客户端做身份认证,有几种常见的做法:
在请求中加签名参数
为每个接入方分配一个密钥,并且规定一种签名的计算方法。要求接入方的请求中必须加上签名参数。这个做法是最简单的,但是需要确保接入方密钥的安全保存,另外还要注意防范replay攻击。其优点是容易理解与实现,缺点是需要承担安全保存密钥和定期更新密钥的负担,而且不够灵活,更新密钥和升级签名算法很困难。
使用标准的HTTP身份认证机制
HTTP Basic身份认证安全性较低,必须与HTTPS配合使用。HTTP Digest身份认证可以单独使用,具备中等程度的安全性。
HTTP Digest身份认证机制还支持插入用户自定义的加密算法,这样可以进一步提高API的安全性。不过插入自定义加密算法在面向互联网的API中用的不是很多。
这个做法需要确保接入方“安全域-用户名-密码”三元组信息的安全保存,另外还要注意防范replay攻击。
优点:基于标准,得到了广泛的支持(大量HTTP服务器端、客户端库)。在服务器端做HTTP身份认证的职责可以由Web Server(例如Nginx)、App Server(例如Tomcat)、安全框架(例如Spring Security)来承担,对应用开发者来说是透明的。HTTP身份认证机制(RFC 2617)非常好地体现了“分离关注点”的设计原则,而且保持了操作语义的可见性。
缺点:这类基于简单用户名+密码机制的安全性不可能高于基于非对称密钥的机制(例如数字证书)。
使用OAuth协议做身份认证
OAuth协议适用于为外部应用授权访问本站资源的情况。其中的加密机制与HTTP Digest身份认证相比,安全性更高。需要注意,OAuth身份认证与HTTP Digest身份认证之间并不是相互取代的关系,它们的适用场景是不同的。OAuth协议更适合于为面向最终用户维度的API提供授权,例如获取隶属于用户的微博信息等等。如果API并不是面向最终用户维度的,例如像七牛云存储这样的存储服务,这并非是OAuth协议的典型适用场景。
对敏感的数据做加密,并且防止篡改,常见的做法有:
部署SSL基础设施(即HTTPS),敏感数据的传输全部基于SSL。
仅对部分敏感数据做加密(例如预付费卡的卡号+密码),并加入某种随机数作为加密盐,以防范数据被篡改。
身份认证之后的授权,主要是由应用来控制。通常应该实现某种基于角色+用户组的授权机制,这方面的框架有不少(例如Spring Security),不过大多数开发团队还是喜欢自己来实现相关功能。
李建业:我不认为安全是RESTful API需要考虑的问题,事实上我觉得这是两个正交的问题。当然,如果使用RESTful API来提供认证、授权和身份管理,那也算是双方有关系,但是这和其它风格的API设计所要考虑的问题似乎没什么区别,不值得特别注意。
但是在具体设计层面,这两者的“正交点”上似乎确实有些问题,因为REST是一个推崇状态无关原则的架构风格,而认证和授权通常基于第三方解决方案,所以往往会出现违背有状态约束的问题,这个地方我也没有特别的想法,当然这个困难和原问题关系不大。
至于WS-族的协议,我不太了解,不太能参与讨论。
丁雪丰:对于RESTful API,常见的安全措施都是可以继续使用的。例如,为了防篡改,可以对全部参数进行签名;为了防范重放攻击可以在请求中增加一次性的Token,或者短时间内有效的Token;对内容加密可以实现数据防泄露……;对于DDoS攻击,各种HTTP流量清洗策略,都可以继续发挥作用,因为这就是基本的HTTP请求。
在授权和认证方面,OAuth 2.0已经基本成熟了,并且得到了广泛地应用。如果可以,接入第三方账户体系是个不错的选择,比如Google和Facebook的,国内的当然也有几个候选。
马钧:个人认为RESTful的安全性分为几个层次,在安全要求较高的场合,可以通过HTTPs这样的加密协议来保证网络层的安全,应用层的安全可以通过OAuth实现认证,而对于资源的访问授权,则只能依靠应用程序来实现了。
InfoQ:如何对RESTful API进行版本控制,请分享您认为实用的做法?
李锟:一个比较简单实用的做法是直接在URI中插入版本号,这样做允许多个版本的API并行运行。
另一个做法是在HTTP请求中加入自定义头信息,标明使用的版本号。不过这个做法其实对浏览器不够友好,简单地使用浏览器+HTML无法测试。
李建业:目前比较好的方式还是在uri设计中添加版本信息,其它方法都不如这个实用。
丁雪丰:个人认为最好的版本化,就是没有明显的版本。在对已发布的服务进行变更时,要尽量做到兼容,其中包括URI、链接和各种不同的表述的兼容,最关键的就是在扩展时不能破坏现有的客户端。例如,要变更一个参数,可以选择同时兼容新旧两种输入,或者保持老参数不动,提供一个新的参数,在文档中必须做出说明,不推荐新用户再继续使用之前的参数。
如果必须要进行不兼容的变更,那么可以选择标记不同的版本号,这时可以选择在路径或参数中增加版本信息。也有做法是增加HTTP标头,只是在调用时会稍有不便,推荐前两种方法。
马钧:RESTfulAPI的版本升级,尽量兼容之前的版本,保证原有的API都能正常工作,可以通过HTTP 301转跳到新的资源。另外一种实用的做法就是在url中保留版本号,同时提供多个版本供客户端使用,如 v1.rest.com 或者 rest.com/v1/ 这样。
InfoQ:HTTP1.1规范中给出的动词对于设计RESTful API够用吗?您在实际项目中会扩展自己的动词吗?在什么情况下需要扩展?
李锟:这个问题取决于设计者如何看待和设计资源。如果资源抽象做的很好,对于某个资源的任何操作,通常都能够映射到CRUD四个类别中。CRUD四个类别对于操作资源来说,绝大多数情况下是完备的。HTTP的GET/POST/PUT/DELETE四个方法,对于CRUD四个类别的操作来说是足够的,映射关系是Create-POST/Retrieve-GET/Update-PUT/Delete-DELETE。
我们通常不会选择创建自己的动词,这样做对于客户端开发者来说,需要更多的学习成本。如果在资源上定义的操作过多,我们会选择拆分出更多的资源。
李建业:一般是够用的,有时一些“不够用”的场景是由于我们没有设计出合理的资源,比如批量操作。但是,正如之前所说的那样,对于某些内部的、传统的(因此模型稳定且已知)系统,API提供者和调用者会有自已的固定动词表,此时没必要拘泥。另外,我不建议扩展动词,一旦扩展了动词,其实已经破坏了我之前说的*“尽可能少的先验信息”*,那么,扩展动词和重新设计动词的成本差别不大。基于这个考虑,我建议尽可能保持动词不变,除非你想重新设计动词表。
丁雪丰:一般情况下,常用的HTTP动词是够用的,并没有出现一定要自己扩展动词的情况。其实,最常用的也就是GET、POST、DELETE和PUT,而HEAD、OPTIONS、TRACE则基本用不太到。如果出现一时找不到合适的动词,安全幂等的操作用GET,其他都可以用POST,在设计资源时稍加考虑即可。
马钧:在我的实际项目中,只用到了POST,PUT,DELETE,GET这四个动词。
InfoQ:今年5月份发布的JAX-RS 2.0规范对于RSTfulAPI的设计最有价值的特性是哪个(些)? 它(们)用于解决什么问题?
李锟:REST开发框架RESTEasy项目负责人Bill Burke,去年写了一篇文章介绍JAX-RS 2.0。
我同意Bill在文章中的观点,在JAX-RS 2.0增加的内容中,最重要的三部分为:
a) Client API——用来规范化JAX-RS客户端的开发方式。
b) Server-side Asynchronous HTTP——用来实现服务器端推送功能,而不需要依靠低效的轮询方式。
c) Filters and Interceptors——用来分离关注点,将鉴权、日志等逻辑与业务逻辑分离开,更好地实现代码重用。
这三部分的内容对于开发者来说都很有用。遵循JAX-RS规范做开发,可以确保服务器端以及客户端代码的可移植性。
李建业:我个人关注异步API这部分,主要是因为流式服务将会越来越多,那将大量需要这类支持。
InfoQ:能否为InfoQ的读者推荐一款实用的RESTful API开发框架,并说明您的推介理由。
李锟:这个问题我就不详细回答了。不同的编程语言有不同的REST开发框架,对于REST的支持程度也不同。开发RESTful API的需求范围很广,可选择的开发框架的范围也很广。保持多样性是繁荣生态环境的基础。像Java就有支持JAX-RS规范的Jersey、RESTEasy、Restlet、Apache CXF,和不支持JAX-RS规范的Spring MVC等等很多框架。这些框架目前都做的不错。我对框架的选择没有倾向性。RESTful API设计的最佳实践应该是通用的,而不是必须依赖某种特定的开发框架。
李建业:不好意思,这个我不太重视,没法推荐,不过我可以解释一下为什么对RESTful API框架不感冒的原因。
REST作为一个架构风格,对我们的系统开发有很大影响,但是这些影响一般是针对架构(例如状态无关)或者设计(例如资源识别)上的,所以一旦涉及到具体实现,主要工作就基本结束了,此时开发框架能做的事也就只有简化编程了(相较而言,有的框架还能起到引导设计的作用),而由于RESTful会抽象动词,所以实现层面中和API规范相关的工作本来就不多,那么框架的价值就更小了。
当然,我们也不可能直接基于servlet/rakc/wsgi来开发,不过一般的编程语言都会提供一些简单的url route/match策略,我们使用这些就足够了。另外,有些框架能帮我们生成全部的动词支持,但这也未必是好事,我一般倾向于按需实现——用到了再支持,这就更不需要太关注开发框架对RESTful的支持了。
丁雪丰:由于本人是Spring的拥护者,工作中也一直在使用Spring,所以在选择框架时会更多地倾向Spring MVC(并不是说别的框架不好,这里有些个人主观的成份)。如果一定要选择其他框架,也要选择能够方便与Spring集成的框架。如果在项目中已经使用了Spring,那么没有什么理由不选择Spring MVC,鉴于目前Spring在各种项目中的高出镜率,相信一般情况下都会选择Spring MVC。
REST的成熟度模型中,第三层就是HATEOAS,Spring目前还提供了Spring Hateoas子项目,对链接、资源等方面的支持都做了一定的增强。
马钧:我目前在实际项目中使用的是Spray,这是一个开源的 REST/HTTP 工具包和底层网络 IO 包,基于 Scala 和 Akka 构建。轻量级、异步、非堵塞、基于 actor 模式、模块化和可测试是Spray的特点。
InfoQ:HTTP2.0规范正在制定当中,您对它的期待是什么?
李锟:我的期待包括两个方面:应该做的和不应该做的。
HTTP/2.0规范应该做的:
与HTTP/1.1协议保持兼容。兼容的含义是说两者可以并存,客户端应用可以根据服务器端的能力,自由地选择使用HTTP/2.0还是HTTP/1.1,而且选择过程对应用来说是透明的。
改进HTTP协议(作为资源的统一接口)之中操作语义表达方式的语法,提高网络传输效率。
更好地模块化,这样HTTP/2.0协议的实现能够更好地模块化。应用程序可根据需要选择适当的模块,而不是要么全有、要么全无。
废弃掉HTTP/1.1协议中一些很少有人用到的部分,例如采用管道(pipelining)方式发送请求。
增加更多的动词,以适应除CRUD之外的其他场景。
HTTP/2.0规范不应该做的:
HTTP/2.0协议不应该把底层的数据加密机制(即SSL)作为必选项。
HTTP/2.0协议不应该背离REST架构风格的约束,尤其是要确保操作语义对于中间组件的可见性。
在上面这两个方面,Roy Fileidng曾经与SPDY协议设计者Mike Belshe发生过激烈争论,详情请看:Roy Fielding谈Google SPDY协议
李建业:对此规范关注不多,不知道会不会有对于流的支持,目前我所知道的只有chunk方式进行简单的支持,但是真正的流需要区分数据通道和控制通道——哪怕是逻辑上的区分,这样就直接对REST风格产生了很大冲击,考虑到流式服务在未来的发展潜力,我特别期待业界在这方面有所进展。
丁雪丰:HTTP 2.0很大程度上是借鉴了Google的SPDY,就我而言,首先,希望这个规范能做到与HTTP 1.1的兼容,使用者如果只认识1.1,那么2.0能优雅“降级”;其次,希望2.0能带来更好的性能,SPDY在这方面还是有所改进的,希望HTTP 2.0能再接再厉;最后,希望这个规范能在最终定稿时附带一个最佳实践,正确引导人们合理地使用HTTP 2.0。
马钧:没研究过,估计即使出来,1.1还有很长的生命周期,不会很快被取代。

如何更好的设计RESTful API

一个好免费api设计的RESTful API,应该具备以下特征:
这个API应该是对浏览器友好的,能够很好地融入Web,而不是与Web格格不入。
1.浏览器是最常见和最通用的REST客户端。好的RESTful API应该能够使用浏览器+HTML完成所有的测试(不需要使用编程语言)。这样的API还可以很方便地使用各种自动化的Web功能测试、性能测试工具来做测试。Web前端应用(基于浏览器的RIA应用、移动App等等)也可以很方便地将多个RESTful API的功能组合起来,建造Mashup类的应用。
这个API中所包含的资源和对于资源的操作,应该是直观和容易理解的,并且符合HTTP协议的要求。
REST开发又被称作“面向资源的开发”,这说明对于资源的抽象,是设计RESTful API的核心内容。RESTful API建模的过程与面向对象建模类似,是以名词为核心的。这些名词就是资源,任何可命名的抽象概念都可以定义为一个资源。而HTTP协议并不是一种传输协议,它实际提供免费api设计了一个操作资源的统一接口。对于资源的任何操作,都应该映射到HTTP的几个有限的方法(常用的有GET/POST/PUT/DELETE四个方法,还有不常用的PATCH/HEAD/OPTIONS方法)上面。所以RESTful API建模的过程,可以看作是具有统一接口约束的面向对象建模过程。
按照HTTP协议的规定,GET方法是安全且幂等的,POST方法是既不安全也不幂等的(可以用来作为所有写操作的通配方法),PUT、DELETE方法都是不安全但幂等的。将对资源的操作合理映射到这四个方法上面,既不过度使用某个方法(例如过度使用GET方法或POST方法),也不添加过多的操作以至于HTTP的四个方法不够用。
2.如果发现资源上的操作过多,以至于HTTP的方法不够用,应该考虑设计出更多的资源。设计出更多资源(以及相应的URI)对于RESTful API来说并没有什么害处。
这个API应该是松耦合的。
RESTful API的设计包括了三个循序渐进、由低到高的层次:资源抽象、统一接口、超文本驱动。正是这三个层次确保了RESTful API的松耦合性。
3.当设计面向互联网的API时,松耦合变成了一种“必须有”的强需求。紧耦合的API非常脆弱,一旦公布出去,服务器端和客户端都无法持续进化。尤其是服务器端,公布出去的接口根本不敢改,改了之后,几乎所有客户端应用立即无法正常工作。REST这种架构风格就是紧耦合API的解毒剂,这个话题可以谈的很深,这里就不展开了。感兴趣的读者可以参考《REST实战》。
这个API中所使用的表述格式应该是常见的通用格式
在RESTful API中,对于资源的操作,是通过在服务器端-客户端之间传递资源的表述来间接完成的。资源的表述可以有很多种格式,并且在响应和请求中的资源表述格式也会有所不同。GET/POST响应中的资源表述格式,常见的有HTML、XML、JSON免费api设计;POST/PUT请求中的资源表述格式,常见的有标准的HTML表单参数、XML、JSON。
4.这些常见表述格式,处理起来非常容易,有大量的框架和库提供支持。所以除非有很合理的要求,通常不需要使用自定义的私有格式。
使用HTTP响应状态代码来表达各种出错情况
HTTP响应状态代码,是HTTP协议这个统一接口中用来表达出错情况的标准机制。响应状态代码分成两部分:status code和reason phase。两部分都是可定制的,也可以使用标准的status code,只定制reason phase。
5.如果一个所谓的“RESTful API”对于任何请求都返回200 OK响应,在响应的消息体中返回出错情况信息,这种做法显然不符合“确保操作语义的可见性”这个REST架构风格的基本要求。
这个API应该对于HTTP缓存是友好的
6.充分利用好HTTP缓存是RESTful API可伸缩性的根本。HTTP协议是一个分层的架构,从两端的user agent到origin server之间,可以插入很多中间组件。而在整个HTTP通信链条的很多位置,都可以设置缓存。HTTP协议内建有很好的缓存机制,可以分成过期模型和验证模型两套缓存机制。如果API设计者完全没有考虑过如何利用HTTP缓存,那么这个API的可伸缩性会有很多问题。

如何更好地设计REST API

由于REST可以降低开发的复杂度免费api设计,提高系统的可伸缩性免费api设计,增强系统的可扩展性,简化应用系统之间的集成,因而得到了广大开发人员的喜爱,同时得到了业界广泛的支持。比如IBM,Google等公司的很多产品都提供了REST API给开发人员;与此同时,大量的开源项目和云计算服务都提供了REST API接口。
而在最近,一些新产品的开发甚至已经几乎完全抛弃了传统的类似JSP的技术, 转而大量使用REST风格的构架设计, 即在服务器端所有商业逻辑都以REST API的方式暴露给客户端, 所有浏览器用户界面使用widget、Ajax、HTML5 等技术,用HTTP的方式与后台直接交互。
那么, 在REST API爆炸式增长的今天, 免费api设计我们应该如何更好的设计我们的接口, 来提高我们的API的可用性,易用性,可维护性与可扩展性呢?本文将从以下方面与您探讨REST API设计方面的最佳实践:
如何规划资源标识结构与URI模式
如何根据应用场景提供内容协商
如何正确的使用HTTP响应代码
如何处理缓存和并发请求
如何利用数据冗余和链接元素
先决条件
如果您具有如下知识与经验,将有助于您阅读和理解本文章的内容 。
REST相关的基本知识;
HTTP协议的基本知识;
一定的Web开发经验。
REST简介
REST是英文Representational State Transfer的缩写,是近年来迅速兴起的,一种基于HTTP、URI以及XML这些现有协议与标准的,针对网络应用的设计和开发方式。它可以降低开发的复杂度,提高系统的可伸缩性。
REST的核心是可编辑的资源及其集合,用符合Atom文档标准的Feed和Entry表示。每个资源或者集合有一个惟一的URI。系统以资源为中心,构建并提供一系列的Web服务。REST的基本概念和原则包括:系统上的所有事物都被抽象为资源;每个资源对应唯一的资源标识;对资源的操作不会改变资源标识本身;所有的操作都是无状态的;等等。
在REST中,开发人员显式地使用HTTP方法,对系统资源进行创建、读取、更新和删除的操作:
使用POST方法在服务器上创建资源
使用GET方法从服务器检索某个资源或者资源集合
使用PUT方法对服务器的现有资源进行更新
使用DELETE方法删除服务器的某个资源
图 1. 用 HTTP 方法操作相册系统资源的简单范例
更好的规划你的资源标识结构与URI模式
REST 中,最基本的莫过于资源标识结构和URI模式了。更好的规划免费api设计他们,是我们的API设计取得成功的最关键的一步。
首先,我们来看看基本资源类型
上文中提到,在REST构架的设计中,系统中的所有事物都被抽象为资源。
在一个文档系统中,文档、目录、注释、草稿等等,是组成系统的资源。
在一个银行系统中,客户信息、理财产品、利率信息、网点信息等等,是组成系统的资源。
在一个航空客票系统中,旅客信息、机票订单、航班信息、机场信息等等,是组成系统的资源。
这些资源,通常在系统中以“Entry”的形式出现。下面的代码样例向您展示了一个常见的“Entry”资源。
清单 1. 一个简单的Entry资源样例

以下是引用片段:
REST API 请求:
GET http://example.com/航班信息/CA827/entry
<entry
<id CA827 </id
<link href="航班信息 /CA827/entry" rel="self"/
<title type="text"CA827 </title
<published2010-08-24T02:35:40.937Z </published
<updated2010-08-24T02:35:40.937Z </updated
<ca:fromBeijing </ca:from
<ca:toChangsha </ca:to
<ca:time09:30:00 </ca:time
<ca:aircraftAB330 </ca:aircraft
<summary type="text"/
</entry
我们会注意到,这些资源,在描述了某种事物的同时,还有可能存在一定的层次结构关系。比如,文档从属于某个目录,注释从属于文档;旅客信息可以从属于机票订单,也可以从属于某个航班。
当我们的资源有这种层次关系的时候,我们不妨在URI模式的设计中,用复合的URI来帮助开发者更好的理解和设计资源。
比如, 针对一个文档的评论, 他的URI模式可以设计成如下:/文件夹/[文件夹名]/文件/[文件名]/评论/[ 评论唯一标示 ]。 这样,在构造和解析URI的过程中, 可以帮助开发者更好的理解系统,设计程序。
其次,我们来看看集合资源类型
资源,除了作为独立个体可以被访问,还可以由多个个体组合成一个集合,在系统中,通常以“feed”的形式存在。资源的集合, 可以是处于相同层次上,有相同从属关系的一组资源,比如一个文件夹下的所有文件; 也可以是根据某种条件查询出来的查询结果的资源集合,比如所有30岁以上40岁以下,拥有100万资产以上客户的名单。
下面,我们来讨论一下设计集合类型资源的REST API时需要考虑的问题。
使用过滤条件来帮助用户更准确地获取数据
我们要返回的资源集合,无论是否有相同从属关系,大部分时候都需要进行必要的过滤,提供足够的过滤参数,查询参数, 能够帮助开发者高效的,准确地获取所需要的数据。 在服务器端过滤数据通常比客户端高效,并且减少了不必要的数据传输,可以大大减少网络开销,提高执行效率。
最常见的过滤条件,是通过URL参数实现,比如/环境工程系/学生? 籍贯=北京性别=女。
很多时候,我们需要制定更加复杂的过滤条件,那么我们可以有两种选择:
首先,我们可以使用正则表达式或者服务器可以理解的语法,比如/环境工程系/学生?filter=age between (15, 18)
其次,我们还可以使用POST方法,携带一个文件来描述复杂的查询条件,文件的格式与语法通常需要在服务器端有相应的设计与定义。不过通常POST方法没有缓存机制,因此不是查询数据的首选。
使用排序来帮助客户端更好的展现数据
虽然进行客户端排序对于开发者来说是件轻而易举的事情,但是直接得到已经排序的返回结果,仍然是大部分开发者所期望的。尤其是很多时候,我们在浏览器,使用 Widget 展示结果,不适宜在客户端存储大量数据进行内存排序。
排序, 通常有2个参数,一个是用来排序的字段,一个是排序的升序降续方式。比如我们可以用支持这样的参数组合的手段,提供基本的排序能力:?sortOrder=ascsortField=age
使用分页来帮助客户端处理大量数据
由于返回的结果可能有几百几千条记录,将这些记录一次性的返回给客户端是不现实的,巨大的网络流量开销和客户端数据区的内存开销,都是我们在应用开发的时候不希望看到的,因此,如果你的集合资源有可能有大量的数据返回,请务必提供分页的功能支持。
我们通常用一个以上参数来制定一个返回结果的区域,比较常见的有下面两种:
一种常见于用固定行数的表格来展示数据,用当前处于第几页和每页返回多少行数据来确定需要的数据, 比如/所有学生?page=5pagesize=50
另外一种常见于用更加灵活的界面展示数据,用从第几行开始,一共返回多少行数据来确定需要的数据, 比如/所有学生?startIndex=27count=22
下面是一个来自IBM developerWorks的API样例,尝试请求该API,你可以看到该集合很好的支持了结果的分页与排序。同时我们从返回的信息中可以看到,每个文档Entry的URI都按照/社区库/[社区库ID]/文档/[文档ID]的复合URI的模式设计的。
清单 2. IBM developerWorks的某个社区文件库的集合资源的API

以下是引用片段:
REST API 请求:
GET https://www.ibm.com/developerworks/mydeveloperworks
/files/form/anonymous/api/communitylibrary
/0a7c97bb-6cf9-4ddb-a918-80994e7b444d/feed?
pageSize=5page=1sK=modifiedsO=dsc
最后,我们来讨论一些特殊资源类型
理想的REST世界,一切事物都抽象为资源,一切操作都抽象为增删改查。然而,所有事物与操作都可以很容易的按照这个规则作抽象吗?让我们看看这个例子:
检入和检出一个文档----这个时候,我们要处理的资源是一个文档,然而增删改查似乎都无法与“检入检出”这个动作进行对应。当然,我们可以在文档资源中,设计一个检入检出状态的元素,通过编辑文档资源来实现。但是,这种设计从自然语义上看,并不是很贴切;并且增加了资源编辑操作的复杂度。
如果我们来定义一个新的集合----“我检出的文档”,用创建一个集合资源来对应检出(创建一个文档锁),用删除一个集合资源来对应检入(删除一个文档锁), 是不是逻辑上可以变得更加清楚?
在REST这个以名词为核心的构架结构中,当你遇到一些动词特性比较强的操作,而又很难用原始资源的增删改查来匹配的时候,不妨换个思路, 通过引入新的逻辑资源集合的方式, 来进行API的设计与规划。
理解和使用内容协商
我们的开发者在发送一个REST API请求的同时,根据应用场景,针对相同的资源,可能会期待不同的返回形式。
比如,我希望根据用户客户端语言,同一个资源的内容可以返回不同的语言。又比如,当我使用Java编程的时候,我希望得到ATOM格式的返回结果,而当我使用JavaScript编程的时候,我希望得到Json格式的返回结果。
因此,我们在设计REST API的时候,应该提供完备的内容协商能力。
使用URL参数进行内容协商
最容易想到的自然是通过URL参数进行控制,我们经常看到形如/航班号/entry? format=JSON这样的URL。这种方式的优势就是简单灵活, 你可以通过任何 URL 参数来组合你的输出格式。
下面是一个来自IBM developerWorks的API样例,尝试请求该API,你可以看到该集合是如何支持不同的输出格式请求的。
清单 3. IBM developerWorks的文件服务标签云的API

以下是引用片段:
REST API请求,要求返回XML格式数据:
GET https://www.ibm.com/developerworks/mydeveloperworks
/files/form/anonymous/api/tags/feed?format=xml
scope=documentpageSize=30sK=cloudsO=dsc
REST API请求,要求返回JSON格式数据:
GET https://www.ibm.com/developerworks/mydeveloperworks
/files/form/anonymous/api/tags/feed?format=json
scope=documentpageSize=30sK=cloudsO=dsc
使用Accept头进行内容协商
使用URL参数,简单灵活,但是也由此带来了设计上的随意和不标准。并且,过多的参数会导致URL的可读性变差,更有甚者,可能会导致URL过长,超出规范,API请求无法执行。
更为标准的内容协商方式是使用HTTP头。我们通常使用Accept来设置我们接受的返回结果的内容格式,用Accept-Charset来设置字符集,用Accept-Encoding来设置数据传输格式,用Accept-Language来设置语言。
使用URI模式进行内容协商
还有一种模式,就是将协商设置直接作为URI的一部分,将不同的返回视为不同的资源,比如/航班号/json来返回JSON格式的结果,用/航班号/atom来返回ATOM格式的结果。
正确的使用HTTP响应代码
作为API的设计者,正确的将API执行结果和失败原因用清晰简洁的方式传达给客户程序是十分关键的一步。 我们确实可以在HTTP的相应内容中描述是否成功,如果出错是因为什么, 然而, 这就意味着用户需要进行内容解析,才知道执行结果和错误原因。因此,HTTP响应代码可以保证客户端在第一时间用最高效的方式获知API运行结果,并采取相应动作。
转载,仅供参考,祝你愉快,满意请采纳。

关于免费api设计和api 免费的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。 免费api设计的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于api 免费、免费api设计的信息别忘了在本站进行查找喔。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:使用java实现手机短信验证全过程
下一篇:免费api软件有哪些(api 免费)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~