面试官了解RESTful吗我听说过。面试官那什么是RESTful我就是用起来很规范挺好的面试官是RESTful挺好的还是自我感觉挺好的我都挺好的。面试官… 把门关上。我… 要干嘛先关上再说。面试官我说出去把门关上。我what 夺门而去文章目录01 前言02 RESTful的来源03 RESTful6大原则1. C-S架构2. 无状态3.统一的接口4.一致的数据格式4.系统分层5.可缓存6.按需编码、可定制代码可选03 RESTful的7个最佳实践1. 版本2.参数命名规范3.url命名规范4. 统一返回数据格式5. http状态码6. 合理使用query parameter7. 多表、多参数连接查询如何设计URL01 前言回归正题看过很多RESTful相关的文章总结参齐不齐结合工作中的使用非常有必要归纳一下关于RESTful架构方式了RESTful只是一种架构方式的约束给出一种约定的标准完全严格遵守RESTful标准并不是很多也没有必要。但是在实际运用中有RESTful标准可以参考是十分有必要的。实际上在工作中对api接口规范、命名规则、返回值、授权验证等进行一定的约束一般的项目api只要易测试、足够安全、风格一致可读性强、没有歧义调用方便我觉得已经足够了接口是给开发人员看的也不是给普通用户去调用。02 RESTful的来源RESTRepresentational State Transfer表象层状态转变如果没听说过REST你一定以为是rest这个单词刚开始我也是这样认为的后来发现是这三个单词的缩写即使知道了这三个单词理解起来仍然非常晦涩难懂。如何理解RESTful架构最好的办法就是深刻理解消化Representational State Transfer这三个单词到底意味着什么。1.每一个URI代表一种资源2.客户端和服务器之间传递这种资源的某种表现层3.客户端通过四个HTTP动词get、post、put、delete对服务器端资源进行操作实现”表现层状态转化”。是由美国计算机科学家Roy Fielding百度百科没有介绍真是尴尬了。Adobe首席科学家、Http协议的首要作者之一、Apache项目联合创始人。03 RESTful6大原则REST之父Roy Fielding在论文中阐述REST架构的6大原则。1. C-S架构数据的存储在Server端Client端只需使用就行。两端彻底分离的好处使client端代码的可移植性变强Server端的拓展性变强。两端单独开发互不干扰。2. 无状态http请求本身就是无状态的基于C-S架构客户端的每一次请求带有充分的信息能够让服务端识别。请求所需的一些信息都包含在URL的查询参数、header、body服务端能够根据请求的各种参数无需保存客户端的状态将响应正确返回给客户端。无状态的特征大大提高的服务端的健壮性和可拓展性。当然这总无状态性的约束也是有缺点的客户端的每一次请求都必须带上相同重复的信息确定自己的身份和状态这也是必须的造成传输数据的冗余性但这种确定对于性能和使用来说几乎是忽略不计的。3.统一的接口这个才是REST架构的核心统一的接口对于RESTful服务非常重要。客户端只需要关注实现接口就可以接口的可读性加强使用人员方便调用。4.一致的数据格式服务端返回的数据格式要么是XML要么是Json获取数据或者直接返回状态码有兴趣的可以看看博客园的开放平台的操作数据的apipost、put、patch都是返回的一个状态码 。自我描述的信息每项数据应该是可以自我描述的方便代码去处理和解析其中的内容。比如通过HTTP返回的数据里面有 [MIME type ]信息我们从MIME type里面可以知道数据的具体格式是图片视频还是JSON客户端通过body内容、查询串参数、请求头和URI资源名称来传送状态。服务端通过body内容响应码和响应头传送状态给客户端。这项技术被称为超媒体或超文本链接。除了上述内容外HATEOS也意味着必要的时候链接也可被包含在返回的body或头部中以提供URI来检索对象本身或关联对象。下文将对此进行更详细的阐述。如请求一条微博信息服务端响应信息应该包含这条微博相关的其他URL客户端可以进一步利用这些URL发起请求获取感兴趣的信息再如分页可以从第一页的返回数据中获取下一页的URT也是基于这个原理。4.系统分层客户端通常无法表明自己是直接还是间接与端服务器进行连接分层时同样要考虑安全策略。5.可缓存在万维网上客户端可以缓存页面的响应内容。因此响应都应隐式或显式的定义为可缓存的若不可缓存则要避免客户端在多次请求后用旧数据或脏数据来响应。管理得当的缓存会部分地或完全地除去客户端和服务端之间的交互进一步改善性能和延展性。6.按需编码、可定制代码可选服务端可选择临时给客户端下发一些功能代码让客户端来执行从而定制和扩展客户端的某些功能。比如服务端可以返回一些 Javascript 代码让客户端执行去实现某些特定的功能。提示REST架构中的设计准则中只有按需编码为可选项。如果某个服务违反了其他任意一项准则严格意思上不能称之为RESTful风格。03 RESTful的7个最佳实践1. 版本如github开放平台https://developer.github.com/v3/就是将版本放在url简洁明了这个只有用了才知道一般的项目加版本v1v2v3?好吧这个加版本估计只有大公司大项目才会去使用说出来不怕尴尬我真没用过。有的会将版本号放在header里面但是不如url直接了当。https://example.com/api/v1/2.参数命名规范query parameter可以采用驼峰命名法也可以采用下划线命名的方式推荐采用下划线命名的方式据说后者比前者的识别度要高可能是用的人多了吧因人而异因团队规范而异吧。https://example.com/api/users/today_login 获取今天登陆的用户https://example.com/api/users/today_loginsortlogin_desc 获取今天登陆的用户、登陆时间降序排列3.url命名规范API 命名应该采用约定俗成的方式保持简洁明了。在RESTful架构中每个url代表一种资源所以url中不能有动词只能有名词并且名词中也应该使用复数。实现者应使用相应的Http动词GET、POST、PUT、PATCH、DELETE、HEAD来操作这些资源即可不规范的的url冗余没有意义形式不固定不同的开发者还需要了解文档才能调用。https://example.com/api/getallUsersGET获取所有用户https://example.com/api/getuser/1GET获取标识为1用户信息https://example.com/api/user/delete/1GET/POST删除标识为1用户信息https://example.com/api/updateUser/1POST更新标识为1用户信息https://example.com/api/User/addPOST添加新的用户规范后的RESTful风格的url形式固定可读性强根据users名词和http动词就可以操作这些资源https://example.com/api/usersGET获取所有用户信息https://example.com/api/users/1GET获取标识为1用户信息https://example.com/api/users/1DELETE删除标识为1用户信息https://example.com/api/users/1Patch 更新标识为1用户部分信息,包含在body中https://example.com/api/usersPOST添加新的用户4. 统一返回数据格式对于合法的请求应该统一返回数据格式这里演示的是jsoncode——包含一个整数类型的HTTP响应状态码。status——包含文本”success””fail”或”error”。HTTP状态响应码在500-599之间为”fail”在400-499之间为”error”其它均为”success”例如响应状态码为1XX、2XX和3XX。这个根据实际情况其实是可要可不要的。message——当状态值为”fail”和”error”时有效用于显示错误信息。参照国际化il8n标准它可以包含信息号或者编码可以只包含其中一个或者同时包含并用分隔符隔开。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 进行返回publicclassApiResult:ApiResult{publicnewstaticApiResultTError(stringmessage){returnnewApiResultT{Code1,Messagemessage,};}[JsonProperty(data)]publicTData{get;set;}}publicclassApiResult{publicstaticApiResultError(stringmessage){returnnewApiResult{Code1,Messagemessage,};}publicstaticApiResultTOkT(Tdata){returnnewApiResultT(){Code0,Message,Datadata};}/// summary/// 0 是 正常 1 是有错误/// /summary[JsonProperty(code)]publicintCode{get;set;}[JsonProperty(msg)]publicstringMessage{get;set;}[JsonIgnore]publicboolIsSuccessCode0;}5. http状态码在之前开发的xamarin android博客园客户端的时候patch、delete、post操作时body响应里面没有任何信息仅仅只有http status code。HTTP状态码本身就有足够的含义根据http status code就可以知道删除、添加、修改等是否成功。(ps:有点linux设计的味道哦没有返回消息就是最好的消息表示已经成功了)服务段向用户返回这些状态码并不是一个强制性的约束。简单点说你可以指定这些状态但是不是强制的。常用HTTP状态码对照表HTTP状态码也是有规律的1**请求未成功2**请求成功、表示成功处理了请求的状态代码。3**请求被重定向、表示要完成请求需要进一步操作。 通常这些状态代码用来重定向。4** 请求错误这些状态代码表示请求可能出错妨碍了服务器的处理。5**服务器错误这些状态代码表示服务器在尝试处理请求时发生内部错误。 这些错误可能是服务器本身的错误而不是请求出错。6. 合理使用query parameter在请求数据时客户端经常会对数据进行过滤和分页等要求而这些参数推荐采用HTTP Query Parameter的方式实现比如设计一个最近登陆的所有用户 https://example.com/api/users?recently_login_day3搜索用户并按照注册时间降序 https://example.com/api/users?recently_login_day3搜索用户并按照注册时间升序、活跃度降序 https://example.com/api/users?qkeysortcreate_title_asc,liveness_desc关于分页看看博客园开放平台分页获取精华区博文列表 https://api.cnblogs.com/api/blogposts/picked?pageIndex{pageIndex}pageSize{pageSize}返回示例[{“Id”:1,“Title”:“samplestring2”,“Url”:“samplestring3”,“Description”:“samplestring4”,“Author”:“samplestring5”,“BlogApp”:“samplestring6”,“Avatar”:“samplestring7”,“PostDate”:“2017-06-25T20:13:38.89213508:00”,“ViewCount”:9,“CommentCount”:10,“DiggCount”:11},{“Id”:1,“Title”:“samplestring2”,“Url”:“samplestring3”,“Description”:“samplestring4”,“Author”:“samplestring5”,“BlogApp”:“samplestring6”,“Avatar”:“samplestring7”,“PostDate”:“2017-06-25T20:13:38.89213508:00”,“ViewCount”:9,“CommentCount”:10,“DiggCount”:11}]7. 多表、多参数连接查询如何设计URL这是一个比较头痛的问题在做单个实体的查询比较容易和规范操作但是在实际的API并不是这么简单而已这其中常常会设计到多表连接、多条件筛选、排序等。比如我想查询一个获取在6月份的订单中大于500元的且用户地址是北京用户年龄在22岁到40岁、购买金额降序排列的订单列表https://example.com/api/orders?order_month6order_amount_greater500address_city北京sortorder_amount_descage_min22age_max40从这个URL上看参数众多、调用起来还得一个一个仔细对着而且API本身非常不容易维护命名看起来不是很容易不能太长也不能太随意。在.net WebAPI总我们可以使用属性路由属性路由就是讲路由附加到特定的控制器或操作方法上装饰Controll及其使用[Route]属性定义路由的方法称为属性路由。这种好处就是可以精准地控制URL而不是基于约定的路由简直就是为这种多表查询量身定制似的的。 从webapi 2开发现在是RESTful API开发中最推荐的路由类型。我们可以在Controll中标记Route[Route(“api/orders/{address}/{month}”)]Action中的查询参数就只有金额、排序、年龄。减少了查询参数、API的可读性和可维护行增强了。https://example.com/api/orders/beijing/6?order_amount_greater500sortorder_amount_descage_min22age_max40这种属性路由比如在博客园开放的API也有这方面的应用如获取个人博客随笔列表请求方式GET 请求地址https://api.cnblogs.com/api/blogs/{blogApp}/posts?pageIndex{pageIndex}(ps:blogApp博客名)作者信息【文章信息】作者-张林原文链接-https://blog.csdn.net/kebi007/article/details/102927209【原创公众号】dotNet全栈开发。【简介】CSDN 博客专家 xamarin跨平台开发者博客园app开发者ps虽然下载量还行10万并没有什么大用这是一个坚持原创的技术公众号每天坚持推送各种 dotNet 基础/进阶文章编程技巧爬虫实战面试经验xamarin开发系列不定期分享各类资源。【福利】送你新人大礼包一份关注微信公众号后台回复“CSDN” 即可获取版权声明本文为CSDN博主「dotNet全栈开发」的原创文章遵循 CC 4.0 BY-SA 版权协议转载请附上原文出处链接及本声明。————————————————版权声明本文为CSDN博主「dotnet全栈开发」的原创文章遵循 CC 4.0 BY-SA 版权协议转载请附上原文出处链接及本声明。原文链接https://blog.csdn.net/kebi007/article/details/103655685
阅读完成 · 觉得有帮助?