使⽤C#开发HTTP服务器系列之构建RESTfulAPI
到⽬前为⽌,“使⽤C#开发HTTP服务器”这个系列系列⽂章⽬前已经接近尾声了,虽然我们在服务器功能的完整性(如⽀持并发、缓存、异步、Htts等)上没有再继续深⼊下去,可是我们现在已经具备了⼀个基本的服务器框架啦,所以更多深层次的问题就需要⼤家根据⾃⼰的需要来扩展了,因为写博客更多的是⼀种“记录-输出-反馈”的⼀个过程,所以我更希望⼤家在看完我的博客后能对我有所反馈,因为抄博客上的代码实在是太⽆聊啦!好了,保持愉悦的⼼情我们下⾯来引出今天的话题:构建RESTful API。RESTful API,这个概念或许你曾经听说过,可能它和我们所熟悉的各种Web息息相关,甚⾄在某种意义上来讲它并不是⼀种新的技术,⽽这⼀切的⼀切归根到底都是在问⼀个问题,即⽹站真的是Web的唯⼀形态吗?
什么是RESTful API调用webservice服务
  什么是RESTful API?⾸先,REST即REpresentational State Transfer,通常被翻译为“表述性状态传输”或者“表述性状态转移”,它最早出⾃Roy Fielding的《Archltectural Styles and the Design of Network-based Software Arcltechures》这篇论⽂,作者曾经参与HTTP协议和Apache Web Server的设计,所以REST实际上是⼀个和HTTP协议联系⾮常紧密的⼀种设计思想。⽽从这个题⽬中我们可以到三个关键词:
架构样式——(Archltectural Styles)
软件架构——(Software Arcltechures)
⽹络为基础——(Network-based)
所以从我个⼈⾓度来理解REST,我更倾向于将REST理解为⼀种以⽹络为基础的设计风格,因此REST从本质上来讲解决的是如何正确地使⽤Web标准的问题。
  以国内为例,当Google的Chrome浏览器选择以Chormium这种形式开源以后,国内⼚商纷纷表⽰跟进以双核为主要特点进⾏了新⼀轮的互联⽹⼊⼝争夺战,虽然从技术⾓度来讲这让Chorme浏览器更加流⾏,可我们更应该注意到不同的⼚商纷纷建⽴起⾃⼰的护城河,以牺牲Web的统⼀性和标准性来满⾜其商业竞争的需要,所以我们看到了即使在HTML5定稿以后,在不同浏览器对HTML5的⽀持区别依然⾮常⼤。带动了⼤量可以在朋友圈内流传的“H5”媒介,可是这个东西从来就不是HTML5,⽽内置的QQ浏览器内核更是以各种不兼容让开发者为此殚精竭虑,所以你问我REST是什么的时候,我会回答它是⼀种风格上统⼀的Web API,⽽根据百科中的描述REST通常被这样定义:
* REST是⼀组架构约束条件和原则,⽽满⾜这些约束条件和原则的应⽤程序就是RESTful。
* REST的⽬标是构建可扩展的Web Service,它是⼀种更简单的SOAP协议以及以WSDL为基础的We
bService的替代。
* REST采⽤的是HTTP协议并通过HTTP中的GET、POST、PUT、DELETE等动词收发数据。
* REST希望通过HTTP来完成对数据的元操作,即传统的CRUD(Create、Read、Update、Delete)分别对应GET、POST、PUT、DELETE,这样就统⼀了数据操作的接⼝,实现在不同平台上提供⼀套相同的服务。
* REST是⼀种⾯向服务的、分布式的API设计风格。
从WebService看REST
  在这⾥我们提到了SOAP、WSDL、RPC等概念,这是因为从某种意义上来讲,REST是这些概念的⼀种延伸。以我们熟悉的WebService为例,当我们需要从⽹络上获取天⽓预报信息时,我们可以采取两种思路,第⼀种是通过抓包分析相关天⽓预报⽹站来获取信息,第⼆种是通过调⽤互联⽹上提供的WebService来获得信息。虽然这两种⽅法在技术上具有相似性和可⾏性,可是我觉得对开发者来讲,除了技术层⾯的突破以外在道德层⾯的坚守更为重要,我们说”⼈⽆德不⽴,国⽆德不兴”正是如此,所以我们这⾥强烈推荐第⼆种思路。WebService能够让我们像调⽤⼀个⽅法⼀样获取信息,那么对我们来讲WebService到底是什么呢?
  WebService⾸先是⼀种服务,它不需要客户端提供额外的软件⽀持,只要客户端⽀持HTTP协议和XML这样两个特性就可以了。⽽对WebService⾃⾝来讲,它本⾝就是⼀种⾃我描述型的设计,所以服务端和客户端可以通过它来了解响应和请求的内容及格式,因为XML是⼀种平台⽆关、语⾔⽆关的⽂档结构,所以WebService是⼀种可以跨平台的Web API。WebService能够让客户端像调⽤本地代码⼀样调⽤服务端代码,所以WebService是⼀种分布式计算的Web应⽤程序组件。我们对WebService下了如此多的定义,其实核⼼是什么呢?核⼼是WebService是⼀种基于HTTP协议和XML的Web API。
  好了,现在我们再来说说什么是SOAP和WSDL。事实上,这些概念听起来都⾮常地学术,可是我保证这对我们理解REST会有所帮助。⾸先,SOAP即简单访问对象协议(Simple Object Access Protocol),听起来感觉⾮常⾼⼤上吗?然⽽这是⼀个“唯⼀没有发明任何新技术的技术”。因为它是⼀个访问Web服务的协议,如同HTTP协议定义了访问Web的协议⼀样,SOAP在HTTP协议的基础上,采⽤XML定义了消息协议,所以SOAP本质上是使⽤XML进⾏通信的HTTP协议,这样听起来是不是⾮常熟悉啦,因为我们熟悉的AJAX同样是采⽤XML进⾏通信,所不同的是AJAX是运⾏在浏览器中的且其主要⽬的是实现页⾯的⽆刷新更新。需要说明的是,虽然SOAP的基础HTTP协议是基于TCP/IP协议的,可是SOAP是具有穿透防⽕墙的能⼒的,对此有兴趣的朋友可以⾃⾏了解,我们这⾥因为篇幅有限所以就不做详细说明啦!
  接下来,WSDL即Web服务描述语⾔(Web Service Description Language),我对它的理解是提供了
⼀个WebService的⽂档,因为从定义可以看出,它是⼀个基于XML的⽤于描述Web服务以及如何访问Web服务的语⾔,Web服务提供者通过它可以告知使⽤者当前Web服务访问的规范和说明,⽽Web使⽤者通过它可以在满⾜平台⽆关性和语⾔⽆关性的情况下快速进⾏开发,所以综合下来看,WebService和REST都能为我们提供类似地服务需求,关于两者或者说REST能为我们带来哪些不⼀样的体验,我们将在本⽂的第⼆部分说明。
从WCF看REST
  我觉得对技术⽽⾔,我们每个⼈都应该试图去发现技术背后真正美的东西,就像我们在了解了WebService,并发现它和REST从本质上来讲都是⼀个东西的时候,这个时候我们应该直接去了解REST给我们带来了哪些不⼀样的东西。可是事实上因为开发者使⽤的平台和语⾔的多样性,让开发者再这个过程中不得不去对平台或者语⾔造成依赖,⽽当每个⼚商都试图建⽴⼀套⾃⼰的标准或者框架的时候,它对开发者造成的这种依赖感就越发地强烈。虽然我⽬前的⼯作是做.NET开发,可是事实上我最喜欢的只有微软的C#语⾔⽽已。这⾥我们简单介绍下WCF,WCF即Windows Communication Foundation是由微软发展的⼀组数据通信的应⽤程序开发接⼝,它是.NET框架的⼀部分,
从.NET Framework 3.0开始引⼊,其设计⽬标是整合不同进程的通信、不同系统间的通信、C/S架构通信等等通信⽬标,所以对.NET开发者⽽⾔它是⼀个“全家桶”般的存在,我们到底需要“⼩⽽美”还是“⼤⽽全”,这是⼀个问题。
  回到我们关注本⾝,WCF整合了Web服务、.NET Remoting、消息队列和Enterprise Services的功能并将其整合在Visual Studio中,显然对我们⽽⾔,我们关注的核⼼依然在Web服务。⾸先,我们要明确的是WebService这个是⾏业标准,即WebService规范,这是⼀个和平台、和语⾔⽆关的标准,⽽微软的ASP.NET WebService是ASP.NET框架的组成部分,我不喜欢ASP.NET的⼀个原因就是我们常常认为⽹站是Web技术的核⼼⽽Web服务不是,更离谱的是我们认为开发⼀个Web服务器或者⼀个WebService⼀定要采⽤XXX框架,虽然使⽤Web 框架、写业务代码都是技术能⼒的⼀种体现,可是不求甚解真的⽆法让我安⼼。那么WCF呢?其实WCF本质上是将ASP.NET WebService 和微软的相关技术如Enterprise Services(COM+)、.NET Remoting、MSMQ消息队列等进⾏了整合,为什么要整合在⼀起呢?因为从宏观上来讲,跨进程、跨机器、跨⽹络都属于通信的范畴,所以我们现在回过头来看,这些东西玩来玩去有什么稀奇,归根到底还不是HTTP协议啊,我们追求新的技术并没有错,错误的是我们将希望寄托在技术本⾝,⽽不是我们⾃⼰。
让REST理解起来简单点
  我们从最初接触到REST的云⾥雾⾥,到翻来覆去地讲述WebService,其实我的⽬的只有⼀个,那就是告诉⼤家,Web技术发展到今天,从本质上来将变化并没有太⼤,可是为什么我们会看到前端领域每隔⼀段时间就会有新的框架产⽣呢?回答这个问题⾮常简单,所有的框架的提出都是因为某种业务的背景需要,⽽所有的业务⽆⼀不是因为⼈类增加了其复杂性,所以当你下来看待这⼀切的时候,你
发现从WebService到REST其实变化都是⾮常细微的东西,与其在新技术⾥疲于奔命不如静下⼼来学习好HTML、CSS和JavaScript,虽然JavaScript是⼀个垃圾的语⾔,可是有时候它会让我们这些后端程序开发者都懵逼呢,哈哈,所以现在是时候给REST⼀个简单的定义:
REST是⼀种使⽤URL来定位资源,使⽤HTTP请求描述操作的Web服务规范。
REST的约束条件和原则
  我们说REST本质上是Web服务的⼀种规范,⼀种思想,所以单独来说REST是没有意义的,这意味着,如果我们要深⼊了解REST,就需要了解它的约束条件和原则,下⾯我们就来说说这个问题。
资源(Resources)
  在REST 中资源是整个架构或者说整个⽹络处理的核⼼,那么什么是资源呢?在我们传统的观念中,资源是指服务器上的⼀个⽂件,⽽在REST ⾥资源则是指⼀个URL 。URL 即统⼀资源定位,⽽我们都知道通过URL 可以访问互联⽹上的资源,所以在REST ⾥这种对资源的指向性更加强烈,并且在这⾥资源的范畴会被⽆限放⼤⽽并⾮局限在⽂件本⾝,例如:由此我们注意到REST 在形式上更加趋向API 设计,⽽我们获取的资源则通过⼀定的形式进⾏统⼀⽽规范化的表达,因此REST 实现了让不同的平台共享⼀套API 这样的愿望,这是⼀件⾮常美好的事情,这个世界上的技术阵营举不胜数,⽽它们为
了各⾃的利益建⽴⼀套封闭、臃肿的体系框架,很多时候当我们不需要这样的“全家桶”并且希望“跨平台”的时候,REST 将会是⼀个不错的选择。
表现形式(Representational)
  在REST 中表现形式作为我们对资源请求的⼀个结果的呈现,通过对HTTP 协议的学习我们已经知道,服务器会给客户端返回什么形式的信息,这⼀点取决于服务器响应报⽂中相关头部字段,⽽对REST 来讲,它通常会采⽤XML 或者JSON 来告诉请求者请求的结果,因为JSON 相⽐XML 所含的冗余信息较少,所以⽬前更加倾向于或者说流⾏使⽤JSON 作为请求结果的表现形式。
状态变化(State Transfer)
  虽然我们⼀再强调HTTP 协议是⽆状态,这主要体现在HTTP 请求与请求、
HTTP 响应与响应的上下⽂⽆关性上。在REST 中,我们所说状态变化更多是指HTTP 中的GET 、POST 、DELETE 等动词实现。具体来讲,虽然这⼀点我们在前⾯有所提及我们来看下⾯的简单⽰例:
除此之外,我们注意到REST 基于HTTP 协议,所以HTTP
协议中的状态码对它来讲同样适⽤,例如最常⽤的200表⽰成功、500表⽰服务器内部错误、404表⽰⽆法到请求资源等等。
如何构建REST 风格的API
  如何构建REST 风格的API?这是这篇⽂章的最后⼀个问题,相信⼤家在阅读这篇⽂章的时候会感到疲惫吧,我想说写作者的疲惫不⼀定会⽐阅读者的疲惫要轻,现在到了这篇⽂章⾥最难的部分啦,这可⽐我们花费⼤量篇幅来讲什么是REST 要更有意义,这是真正的说起来容易做起来难,在正式开始实践以前,我们⾸先提出下⾯的最佳实践:
URLRoot 采⽤下⾯这样的结构:
URL 使⽤名词⽽⾮动词:
api .qc /v1/feed 表⽰获取某⼈的最新Feed api .qc /v1/friends 表⽰获取某⼈的好
友列表api .qc /v1/profile 表⽰获取某⼈的详细信息
1
2
3GET someurl/tasks 表⽰获取全部的tasks POST someurl/tasks 表⽰创建⼀个新的task GET someurl/tasks/{id} 表⽰获取⼀个指定id 的task PET someurl/tasks/{id} 表⽰更新⼀个指定id 的task DELETE  someurl/tasks/{id} 表⽰删除⼀个指定id 的task
1
2
3
4
5
返回含义明确的结果(这是我为什么推荐使⽤JSON的理由)
  好了,这篇⽂章我⽬前能够理解并输出给⼤家的只有这些啦,关于具体在Web开发中我们如何去实现RESTful API,这个我觉得并没有⼀个固定的⽅法吧,⽽且我现在编写的这个服务器只⽀持Get和Post两种类型,如果要实现⼀个完整的RESTful API架构,还需要很长的时间去探索,这篇⽂章写得我的确有些疲惫,所以有不周的地⽅希望⼤家谅解,后续更新关注我的项⽬就好啦,谢谢⼤家!

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。