ASP.NET Core与RESTful API 开发实战(txt+pdf+epub+mobi电子书下载)


发布时间:2020-06-12 20:08:23

点击下载

作者:杨万青

出版社:人民邮电出版社有限公司

格式: AZW3, DOCX, EPUB, MOBI, PDF, TXT

ASP.NET Core与RESTful API 开发实战

ASP.NET Core与RESTful API 开发实战试读:

前言

编写背景微软于2016年推出.NET Core和ASP.NET Core。作为一个全新的开发平台,.NET Core对.NET Framework框架进行了重大的改进,解决了.NET Framework的一个非常明显的缺陷,实现了跨平台性。使用.NET Core能够开发出适用于各种平台以及各种不同类型的应用,如Web应用程序、微服务、控制台程序、Windows桌面应用(自.NET Core 3.0起)等,并能够轻松地部署到各个平台上。同时,.NET Core沿用了.NET Framework框架的优点,使.NET开发人员能够顺利上手并在工作中使用。.NET Core从发布之初就加入开源组织,并受到开发者社区的支持,目前.NET Core已经达到2.2版本,其成熟性、稳定性、高性能、模块化等特点将帮助开发者开发出适用于各种场景的企业级应用。作为.NET Core平台的重要角色,ASP.NET Core旨在开发现代主流的Web应用程序。与.NET Core一样,ASP.NET Core同样具有跨平台、开源、模块化、高性能等特点,这些特点使它完全超越了ASP.NET。ASP.NET Core还具有一些重要特点,如内置依赖项注入、轻型的高性能模块化HTTP请求管道、灵活的配置与日志系统等,使开发者能够轻松地开发出更灵活、更安全和高质量的Web应用程序。同时,ASP.NET Core内置了对云平台和容器的支持,使它能够快速地部署到不同的平台中。自从2000年Roy Thomas Fielding在其博士论文中首次提出REST后,REST一直就是人们讨论的话题,并且不断地应用于各种技术的实现中。作为一种软件架构风格,REST旨在构建简单、可靠、高性能、高伸缩性的Web应用。然而,由于它并不像标准一样具有详尽的定义、说明与规则,并且开发者易受其他Web服务开发风格的影响,因此多数人对于它的认识与理解不够全面,甚至存在一定程度上的误解。本书以ASP.NET Core与REST为主题,介绍了如何使用ASP.NET Core开发出规范的RESTful API应用。本书不仅详细地介绍了REST、REST约束以及HTTP协议,还深入介绍了ASP.NET Core及其重要性。充分理解ASP.NET Core与REST有助于开发者设计出规范的RESTful API。本书内容本书系统介绍ASP.NET Core与RESTful API应用的开发,共分为10章。前3章重点介绍理论知识,后7章主要讲述实践操作。前3章的理论为后7章的实践提供了支持,如第1章介绍的HTTP消息头和状态码、第3章介绍的ASP.NET Core核心特性,会在后7章中经常提及并用到。这种从理论到实践、由浅入深的学习方式有助于读者进一步掌握所学的内容。如果你刚开始学习.NET Core开发,建议按照章节顺序阅读本书。从第4章开始的项目实践将带领读者一步一步地开发RESTful API应用,从项目的创建到实现对资源的操作,从使用Entity Framework Core到高级查询与日志,从为项目添加认证功能到为项目应用ASP.NET Core提供的各种安全特性,从测试到部署,这一系列内容贯穿了一个实际项目的整个开发流程。读者若能从头到尾实践本书中项目的开发流程,将会受益匪浅。同时,在介绍项目开发的过程中,对于遇到的新知识,本书也进行了必要的理论性介绍,如第4章中的仓储模式、第7章中的HTTP缓存、第8章中的CORS、第10章中的Docker与Azure等。本书主要内容如下。第1章介绍API与REST的基本概念、REST约束、HTTP协议,以及REST中资源表述常用的JSON格式与XML格式等。第2章介绍.NET Core、.NET Standard以及ASP.NET Core,讨论ASP.NET Core自2.0后各个版本新增加的特性与变化,展示开发环境的设置以及如何开始创建第一个Web API应用。第3章深入剖析ASP.NET Core提供的重要特性,如启动与Kestrel服务器、中间件、依赖注入、MVC、配置、日志、错误处理。第4章介绍实例项目(该项目将贯穿本书后面的章节)的创建,讨论如何准备测试数据、仓储模式,以及如何实现对资源的各种操作,如获取、创建、删除、更新等,最后讨论内容协商及其实现方式。第5章介绍Entity Framework Core以及如何在项目中使用它,并使用它替换原来的内存数据源方式,以及使用异步方式替换原来的同步方式。第6章介绍分页、过滤、搜索、排序的实现,以及如何记录日志并处理异常。第7章介绍较为复杂的主题,包括缓存以及不同种类缓存的实现方式、并发控制的实现方式、API版本、HATEOAS,以及GraphQL及其实现。第8章介绍如何保护API应用程序,包括为应用程序添加认证功能、使用Identity保存用户信息、使用HTTPS与HSTS。该章还会讲解数据保护API和用户机密的概念与使用,以及跨域资源访问及其实现方式。第9章介绍如何对应用程序进行单元测试、集成测试,并为其创建OpenAPI文档。第10章介绍如何将应用程序部署到不同的位置,如IIS、Docker以及Azure,同时介绍Docker与Azure的概念与基本操作。建议与反馈完成本书的写作是一件不容易的事。本书尽可能涵盖相关的知识点,并尽力确保内容的正确性,使读者能够从中有所收获。然而由于个人水平有限,书中疏漏之处在所难免,如果你在学习过程中发现书中的错误或对本书有任何建议和意见,既可以告诉作者或本书编辑,也可以提交到异步社区中,我们将非常感激。作者邮箱:ictcm@outlook.com编辑邮箱:zhangshuang@ptpress.com.cn致谢感谢我的家人在我写作期间给予我的支持和包容,也感谢那些帮助我解决疑问并给出建议的技术专家和同事。最后,感谢本书编辑为本书提供的指导与建议。资源与支持本书由异步社区出品,社区(https://www.epubit.com/)为您提供相关资源和后续服务。提交勘误作者和编辑尽最大努力来确保书中内容的准确性,但难免会存在疏漏。欢迎您将发现的问题反馈给我们,帮助我们提升图书的质量。当您发现错误时,请登录异步社区,按书名搜索,进入本书页面,点击“提交勘误”,输入勘误信息,单击“提交”按钮即可。本书的作者和编辑会对您提交的勘误进行审核,确认并接受后,您将获赠异步社区的100积分。积分可用于在异步社区兑换优惠券、样书或奖品。与我们联系我们的联系邮箱是contact@epubit.com.cn。如果您对本书有任何疑问或建议,请您发邮件给我们,并请在邮件标题中注明本书书名,以便我们更高效地做出反馈。如果您有兴趣出版图书、录制教学视频,或者参与图书翻译、技术审校等工作,可以发邮件给我们;有意出版图书的作者也可以到异步社区在线提交投稿(直接访问http://www.epubit.com/ selfpublish/submissionwww.epubit.com/selfpublish/submission即可)。如果您是学校、培训机构或企业,想批量购买本书或异步社区出版的其他图书,也可以发邮件给我们。如果您在网上发现有针对异步社区出品图书的各种形式的盗版行为,包括对图书全部或部分内容的非授权传播,请您将怀疑有侵权行为的链接发邮件给我们。您的这一举动是对作者权益的保护,也是我们持续为您提供有价值的内容的动力之源。关于异步社区和异步图书“异步社区”是人民邮电出版社旗下IT专业图书社区,致力于出版精品IT技术图书和相关学习产品,为作译者提供优质出版服务。异步社区创办于2015年8月,提供大量精品IT技术图书和电子书,以及高品质技术文章和视频课程。更多详情请访问异步社区官网https://www.epubit.com。“异步图书”是由异步社区编辑团队策划出版的精品IT专业图书的品牌,依托于人民邮电出版社近30年的计算机图书出版积累和专业编辑团队,相关图书在封面上印有异步图书的LOGO。异步图书的出版领域包括软件开发、大数据、AI、测试、前端、网络技术等。异步社区微信服务号第1章 REST简介本章内容REST,全称为REpresentational State Transfer,即表述性状态传递,它是一种应用程序的架构风格,用于构造简单、可靠、高性能的Web应用程序。REST提出了一系列约束,遵循这些约束的应用程序称为RESTful API应用。要设计出REST风格的应用,开发者首先应该对REST及其相关概念有基本的理解。因此,本章首先介绍API以及REST的基本概念,并介绍REST所定义的架构约束,同时也会介绍常见的对REST的错误理解。通常情况下,REST是基于HTTP协议而实现的,因此本章会重点介绍HTTP协议,包括媒体类型、HTTP方法、HTTP消息头和状态码等。之后,本章还会提出一些REST的最佳实践,指导开发者设计出优秀的RESTful应用。最后本章还会介绍RESTful API开发中的常见问题,如JSON与XML格式,以及API版本问题。1.1 API与REST1.1.1 什么是APIAPI全称Application Programming Interface,即应用程序编程接口,我们在开发应用程序时经常用到。API作为接口,用来“连接”两个不同的系统,并使其中一方为另一方提供服务,比如在操作系统上运行的应用程序能够访问操作系统所提供的API,并通过这些API来调用操作系统的各种功能。因此,API是一个系统向外暴露或公开的一套接口,通过这些接口,外部应用程序能够访问该系统。在Web应用程序中,Web API具有同样的特性,它作为一个Web应用程序,向外提供了一些接口,这些接口的功能通常是对数据进行操作(如获取或修改数据等),它们能够被外部应用程序,比如桌面应用程序、手机应用甚至其他Web应用程序(如ASP.NET Core MVC视图应用、单页Web应用)等访问并调用。Web API能够实现不同应用程序之间的访问,它与平台或编程语言无关,可以使用不同的技术来构建Web API,如Java、.NET等;调用方也不受Web API使用的平台或技术限制,比如一个使用Java语言开发的Android手机应用可以调用一个使用C#语言开发的ASP.NET Core Web API应用程序。同时,API作为接口,仅向外部应用程序提供了抽象,而不是在其内部实现。这正如高级编程语言中的接口(Interface)一样,调用方无须关心接口如何实现,仅需要调用它所提供的方法即可。此外,Web API由于其自身的特点,不能直接被用户使用,相反地,它通常由开发人员来使用。通过调用Web API,开发人员能够设计出丰富多样的应用。因此,设计良好、有丰富文档的Web API更易于被开发者接受并使用。1.1.2 什么是RESTREST(REpresentational State Transfer)的意思是表述性状态传递,它是Roy Thomas Fielding在2000年发表的博士论文中提出来的一种软件架构风格。作为一种Web服务的设计与开发方式,REST可以降低开发的复杂性,提高系统的可伸缩性。REST是一种基于资源的架构风格,在REST中,资源(Resource)是最基本的概念。任何能够命名的对象都是一个资源,如document、user、order等,通常情况下,它表示Web服务中要操作的一个实体。一个资源具有一个统一的资源标识符(Uniform Resource Identifier,URI),如users/1234,通过资源标识符能够标识并访问该资源。除了单个的资源外,资源集合表示多个相同类型的资源,如users。在系统设计时,不同的实体之间往往存在某种关联关系,如一个用户有多个订单。同样,在REST中,这种关联关系也能够由资源之间的层次关系体现出来,如users/1234/orders/1。由于REST以资源为中心,因此REST接口的端点(Endpoint)均以资源或资源集合结尾,它不像其他形式的Web服务一样以动词结尾,如api/GetUserInfo或api/UpdateUserInfo。在REST中,对资源的动作或操作是通过HTTP方法来完成的,如下:GET http://api.domain.com/users/1234PUT http://api.domain.com/users/1234上例中用到了两个HTTP方法,分别为GET与PUT,它们的作用分别是获取和更新指定资源。当请求方发起请求,修改了资源的状态后,更新后的资源表述应返回给请求方,这也是表述性状态传递的意义。从上面的例子可以看出,REST与HTTP有一定的关系,资源在服务的提供方与请求方之间进行传递,需要借助于协议来约定,比如协议所规定的消息格式等,而HTTP协议则是非常成熟且被广泛使用的网络协议。事实上,HTTP协议完全满足REST中所定义的约束,因此REST能够充分地使用HTTP协议以及其中的功能(如HTTP方法、HTTP消息等),并设计出松耦合的Web服务。1.1.3节将介绍REST约束,在1.2节中将会介绍HTTP协议。1.1.3 REST约束REST定义了6个架构约束(Constraint),遵循这些约束的Web服务是真正的RESTful服务,即REST风格的服务。如果一个系统违反了其中的约束,则不能称其为RESTful,这些约束包括如下。(1)客户端-服务器(Client-Server)客户端-服务器约束体现了关注点分离(Separation of Concerns)原则,使客户端与服务端各自能够独立实现并独立开发,只要它们之间的接口不改变即可;客户端与服务端可以使用不同的技术或编程语言。(2)统一接口(Uniform Interface)统一接口是设计任何RESTful服务的基础,也是区别REST架构风格与其他Web服务风格的最主要约束。系统中的多个组件(包括服务端、客户端,以及可能存在的代理服务器等)都依赖于统一接口。统一接口约束本身又由4个子约束组成,分别如下。● 资源的标识前面提到过,任何能够命名的对象都是一个资源,资源能够通过统一资源标识符来区别。对于Web系统,统一资源标识符通常是一个URL,即统一资源定位符(Uniform Resource Locator)。每个URL代表一个资源或资源集合,当访问一个URL时,能够获取该资源或对它执行相应的操作。● 通过表述操作资源当请求一个资源时,服务器返回该资源的一个表述。该表述表示资源当前的状态,它由表述正文和表述元数据组成,格式通常为JSON、XML和HTML等,比如以下代码是同一资源的两种不同的表述形式。{ "User": { "id": "123", "name": "Tom" }}或 1234 Tom客户端在请求资源时,能够指定期望的表述格式,服务器在返回响应时,在响应中包含了指定表述格式的资源;访问同一个资源的不同格式无须修改资源的标识符,客户端也可以通过资源的表述(而非资源本身)对资源进行操作。● 自描述消息客户端与服务器之间传递的每一条消息都应包含足够的信息,这些信息不仅包含了资源的表述,也包含了资源表述的相关信息(如资源表述的格式与内容长度等),甚至包含了与该资源相关的其他操作信息。● 超媒体作为应用程序状态引擎(HATEOAS)服务器返回的资源表述中不仅要包含资源的表述,也应包含与之相关的链接,这些链接能够对资源执行其他操作,比如当获取资源时,返回的链接中包含更新该资源、删除该资源等链接。关于HATEOAS,第7章会有更详细的介绍。(3)分层系统(Layered System)分层系统约束能够使网络中介(如代理或网关等)透明地部署到客户端与服务器之间,只要它们遵循并且使用前面提到的统一接口约束即可;而客户端和服务端则都不知道网络中介的存在。中间服务器主要用于增强安全、负载均衡和响应缓存等目的。(4)缓存(Cache)缓存是Web架构中最重构的特性之一。客户端或网络中介均能够缓存服务器返回的响应,因此当服务器返回响应时,应指明该响应的缓存特性。对响应进行缓存将有助于减少数据获取延迟以及对服务器的请求,从而提高系统的性能。(5)无状态(Stateless)无状态约束将指明服务器不会记录或存储客户端的状态信息,反之,这些状态信息应由客户端来保存并维护,因此客户端对服务器的请求不能依赖于已发生过的其他请求,当客户端请求服务器时,必须在请求消息中包含所有与之相关的信息(如认证信息等)。(6)按需编码(Code-On-Demand)按需编码约束允许服务器临时向客户端返回可执行的程序代码(如脚本等),返回这些代码主要用于为客户端提供扩展性或自定义的功能。由于客户端必须理解并能够执行服务器返回的代码,因此这一约束增加了客户端与服务器之间的耦合,同时,这一约束是可选的。1.1.4 对REST的错误理解理解REST及其约束,将有助于我们设计RESTful服务或RESTful API。然而在现实中,人们仍然对REST有错误的认识,认为只要有某种特性的API就是RESTful API。这些对REST错误的认识可能包含但不限于以下几种情况。● 任何使用了HTTP方法的API。● 返回JSON的API。● 执行增删查改的API。尽管REST风格的API同样具有上述特点并能够完成上述功能,然而这并不是说具有上述特点的API就是RESTful API。只有遵守了REST约束的API,才能够称为RESTful API。另外,Richardson成熟度模型是衡量API成熟度的一种方式,该模型进一步描述了各种Web API的特征,根据该模型,只有最成熟的API才是RESTful API。在7.4节中,将会更详细地介绍Richardson成熟度模型。除了REST外,另一种常见的API风格是RPC风格,即远程过程调用(Remote Procedure Call)。下面是一个典型的RPC风格的API。GET api.domain.com/getUserInfoGET api.domain.com/UpdateUserInfoREST风格与RPC风格的区别如下。● 在关注点方面,REST面向资源,RPC面向功能。● 在API端点方面,REST的端点是名词、是资源或资源集合,而

RPC的端点是动词、是方法名。● 在执行特点方面,REST对资源执行操作,RPC执行服务器上的

方法。● 在返回结果方面,REST返回请求的资源,而RPC则返回调用方

法的执行结果。1.2 HTTP协议在几乎所有的情况中,REST是基于HTTP协议而实现的,因此深入了解HTTP协议是非常重要且必要的。对于Web开发人员而言,深入了解HTTP协议将有助于开发者开发出更好、更高质量的Web应用程序。此外,当应用程序出现问题时,也能够很容易地找出问题并解决问题。1.2.1 HTTP简介超文本传输(Hyper Text Transfer Protocol,HTTP)协议,是互联网上应用最为广泛的一种网络协议,也是基于TCP/IP协议的应用层协议。其中最为常见的浏览网页的过程,就是通过HTTP协议来传递浏览器与服务器之间的请求与响应的,其流程图如图1-1所示。图1-1 HTTP协议流程图从图1-1中可以看出,HTTP协议采用了请求/响应模型。当客户端(通常是浏览器)发起一个HTTP请求时,它首先会建立起到HTTP服务器指定端口(HTTP协议默认使用80端口)的TCP连接,而HTTP服务器则负责在该端口监听来自客户端的请求。当TCP连接成功建立后,浏览器就会向HTTP服务器发送请求命令,如GET /index.html HTTP/1.1。一旦收到请求,服务器会根据请求向客户端返回响应,其响应内容通常包括一个状态行(如HTTP/1.1 200 OK)和若干个消息头,以及消息正文。消息正文则是资源、请求的文件、错误或者其他信息等。HTTP协议采用的是明文传输数据,这种方式并不安全,因此网景公司(Netscape)在1994年设计了HTTPS协议,即超文本传输安全协议(Hypertext Transfer Protocol Secure),也被称为HTTP over TLS,HTTP over SSL,在第8章中将有关于HTTPS协议更详细的介绍。1.2.2 统一资源定位符统一资源定位符(Uniform Resource Locator),即通常所说的URL,代表网络上一个特定的资源。URL作为URI的子集,一个URL就是一个URI,用于标识并定位资源。对于HTTP而言,当用户在浏览器中输入了一个URL后,意味着他想要获取或查看一些资源。在互联网上,有无穷尽的、各种格式的资源,包括图片、HTML页面、XML、视频、音频、可执行文件和Word文档等,通过URL才能在无数的资源中准确地定位或找到要查看的资源。每一个URL都代表一个不同的资源,因此,要访问HTTP资源,就需要使用URL。例如,当用户想要查看某个公司的网站首页时,就需要在浏览器中输入http://www.….com网址,如果要查看该公司的Logo,则需要输入http://www.….com/images/logo.png网址来获取代表此公司Logo的图片。浏览器会根据用户输入的URL向相应的服务器发送HTTP请求,而服务器会最终将对应的资源返回给客户端,并由浏览器处理后呈现。对于一个URL,如http://www.….com/images/logo.png,它由以下几个部分组成。● http://,这一部分是URL协议,URL协议指明了如何访问一个特

定的资源,如上例中的http://会告诉浏览器要使用HTTP协议,即

超文本传输协议;除了http://外,较为常见的协议还有https://(加密的HTTP协议)、ftp://(文件传输协议)和mailto:(电子邮

件协议)等。● www.….com,这一部分是主机名,主机名会告诉浏览器要访问

的资源所在的服务器名称。DNS(Domain Name System)服务

器会将这个名称解析为一个具体的IP地址,通过这个IP地址可以

找到资源所在的计算机。● /images/logo.png,这一部分是URL路径(Path),它指向服务器

上具体的资源。根据要获取资源的不同,其值也会不同,可以说,

这一部分的变化性最大。它有可能是在服务器的一个真实存在的

文件,比如这里的/images/logo.png,也有可能是由常见的Web

框架生成的动态资源,如http://www.….com/account/index。通常

情况下,当访问某个网页资源时,浏览器会下载其他与此相关的

资源,例如http://www.….com这个网页,它不仅包括文本信息,

也包括图片、JavaScript文件、CSS以及其他资源,所有这些资

源构成了我们在浏览器中看到的页面。除了上述3个主要部分外,URL还常常包括以下几个可选部分。● 端口号,在主机名后面,以冒号隔开,这一部分通常省略。服务

器在这个端口上监听HTTP请求,因此在请求的URL中必须指定

相同的端口。HTTP协议默认使用80端口,如果URL中省略了端

口号,则默认使用此端口;如果HTTP服务器并没有在80端口监

听,而使用了其他端口,则需要在URL中指定端口号,如http://

www.…. com:8080,但这种情况比较少见,通常在开发或调试

Web应用时才会使用其他  端口。● 查询字符串,URL中“?”后面的参数部分,对于http://www.

….com/search?q= hello这样一个URL,“q=hello”即为查询字符

串,其中“q”是参数名,“hello”是参数值,参数名和参数值

用“=”分隔。如果要传递多个参数,则使用“&”来分隔,如

name1=value1&name2=value2。查询的字符串会发送给HTTP 服

务器,并由服务器上的Web应用程序决定如何处理这一部分的内

容。● 锚部分,也称片段(Fragment),即在“#”后面的内容,它用

于指明一个资源的特定位置,例如,http://www.….com/

index.html#contact,该URL将定位到HTML页面中指定的元素。

这一部分内容与上述其他部分都不一样,它不会由服务器处理,

只会由浏览器来处理,也就是说,若更改这一部分的内容,并不

会向服务器再次发起请求,浏览器就会定位到当前资源的不同位

置。由此可见,一个完整的URL形式如下所示。://[:port]/[path][?query][#fragment]1.2.3 媒体类型当HTTP服务器对请求返回响应时,它不仅返回资源本身,也会在响应中指明资源的内容类型(Content Type),也称媒体类型。要指定内容类型,HTTP依赖于MIME标准。MIME(Multipurpose Internet Mail Extensions),即多用途互联网邮件扩展类型,是一种表示文档的性质和格式的标准,因此,媒体类型也被称为MIME类型。MIME标准最初用于电子邮件,它用来告诉客户端具体是什么类型的内容。后来,HTTP协议也使用这一标准,并用作同样的目的。浏览器通过MIME类型来决定如何处理文档,因此服务器在返回响应时为资源设置正确的MIME类型非常重要。例如,对于音频、视频文件,只有设置了正确的MIME类型,才能被HTML语言中的

都使用这种类型。● image/jpeg:表示JPEG图片。● image/png:表示PNG图片。● application/json:表示JSON格式的数据。1.2.4 HTTP消息前面已提到,HTTP是一个采用请求/响应模式的协议。客户端想要获取资源,就应向服务器发出请求,如果服务器能够正确处理来自客户端的请求,并且拥有客户端所请求的资源,它就能正确地响应,同时将资源返回给客户端。反之,如果客户端发出的请求有问题或者服务器上没有所要请求的资源,那么就无法返回客户端所期望的结果。这个请求与响应过程如同“对话”一样,服务器与客户端都必须理解对方的“语言”,这正是HTTP消息所要解决的问题。当客户端向服务器发送请求时,应使用HTTP协议规定格式的消息;而服务器也会向客户端返回规定格式的响应,这样客户端才能够理解。HTTP消息正是服务器和客户端之间交换数据的方式,它有两种类型:请求消息和响应消息。HTTP请求消息和响应消息具有相似的结构,它们都包括以下4部分的内容。● 起始行:即第一行,用于描述要执行的请求,或者是对应的状态,

即成功或失败,这个起始行总是单行的。● HTTP消息头:这些消息头描述了请求或响应的相关属性、配

置、对消息正文的描述等。● 空行:指明消息头已经发送完毕。● 消息正文:包含请求数据(如要创建的资源、HTML表单内容

等),或响应中资源的表述,这一部分可以为空。以下是典型的 HTTP 请求和响应的格式。客户端请求如下:GET / HTTP/1.1User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36 Edge/17.17134Accept-Language: zh-CNAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8Upgrade-Insecure-Requests: 1Accept-Encoding: gzip, deflateHost: microsoft.comConnection: Keep-Alive服务端响应如下:HTTP/1.1 200 OKDate: Mon, 27 Jul 2009 12:28:53 GMTServer: ApacheLast-Modified: Wed, 22 Jul 2009 19:15:56 GMTETag: "34aa387-d-1568eb00"Accept-Ranges: bytesContent-Length: 51Vary: Accept-EncodingContent-Type: text/plain其中,HTTP请求是由客户端发出的消息,用于请求服务器执行某个操作,它的起始行包括以下3项。● HTTP方法:也称HTTP动词,如GET、PUT、POST等,它们描

述要执行的动作。例如,GET表示要获取的资源,PUT表示向服

务器提交数据(创建或修改资源),在下一节中我们将会详细讲

解HTTP方法。● 请求目标:通常是一个URL,它代表所要访问的资源。● HTTP版本:通常是HTTP/1.1。而HTTP响应的起始行被称作状态行,包含以下3项。● 协议版本:通常为HTTP/1.1。● 状态码(Status Code):它表明请求是否成功,常见的状态码

是 200、404、500等。● 状态文本(Status Text):一个简短的文本信息,用于描述状态

码。请求的起始行与响应的状态行,在上例中分别为GET / HTTP/1.1和HTTP/1.1 200 OK。请求的最后一部分是它的正文。注意,并不是所有的请求都有正文,比如获取资源(GET)、获取资源元数据(HEAD),以及删除资源(DELETE)等请求,通常它们不需要正文,而那些要将数据从客户端发送到服务器的HTTP方法,它们若要创建资源或更新资源,就需要提供正文,比如POST和PUT等。响应的最后一部分也是正文。与请求消息一样,不是所有的响应都有正文,状态码如 201或204等的响应,不包含正文。响应消息的正文通常是所请求资源的表述。1.2.5 HTTP方法HTTP定义了一组请求方法,以表明要对指定资源执行的操作。每一个请求消息都必须包括一个HTTP方法,该方法将告诉服务器当前请求要执行哪一种操作。常见的HTTP方法有GET、POST、PUT、DELETE、PATCH、HEAD和OPTIONS等。GET方法的作用是获取指定的资源,它并不会修改资源,因此GET方法是安全的。所谓安全方法,是指不会修改资源的方法。此外,GET方法也是幂等的。所谓幂等,是指多次对同一个URL调用同一个HTTP方法,其效果总是一样的。POST方法的作用是创建资源。POST方法不是安全方法,因为它会修改服务器上的资源,并且也不是幂等方法,多次请求同一个POST操作会产生多个不同的资源。PUT方法的作用是更新资源,因为PUT会修改资源,所以它也不是安全的方法。与POST方法不同的是,PUT方法是幂等的,多次更新同一个资源,其返回结果都是一样的。PUT方法除了更新资源外,当资源不存在时,它还可以创建资源。需要注意的是,尽管POST与PUT方法都可以创建资源,但它们所请求的URI是有区别的,POST请求的URI是资源集合,而PUT则是请求单个不存在的资源,例如:POST http://api.appdomain.com/usersPUT http://api.appdomain.com/users/1234DELETE方法的作用是删除资源,它不是安全的,但它是幂等的,这意味着对同一资源请求多次DELETE方法,效果都是一样的。当第一次对资源调用 DELETE方法时,返回表示操作成功的200 OK状态码,后续再调用DELETE方法,由于资源已经不存在,则应返回404 Not Found状态码。PATCH方法的作用是对资源进行部分更新,它与PUT方法的区别是:PUT会更新指定资源的全部内容,而PATCH可以根据需要仅更新资源的部分字段或属性。HEAD方法与GET方法相同,但它并不返回消息正文,在响应消息中仅包含响应状态码与消息头,该方法常用来检测资源是否存在以及获取资源的元数据。OPTIONS方法用于获取资源支持的操作,服务器在返回的响应中会包含Allow消息头,它的值为HTTP方法列表,例如:Allow: GET, POST综上所述,常见的HTTP方法总结如表1-2所示。表1-2 HTTP方法总结方法名作  用安  幂  称全等GET获取资源是是POST创建资源否否PUT更新指定的资源否是DELETE删除指定的资源否是PATCH对资源进行部分更新否否HEAD与GET方法作用完全一样,但在响应中没有消息是是正文OPTION获取指定资源所支持的操作是是1.2.6 HTTP消息头客户端和服务器之间的请求消息与响应消息中均包含消息头,用来传递附加信息。一个消息头由消息头名称和它的值组成,中间用冒号“:”隔开,比如Content-Type: text/plain。每个消息头都有特定的意义,比如上例的消息头用来指明请求或响应消息中正文的内容类型。HTTP请求与响应中均可包含多个消息头。常见的请求消息头如表1-3所示。表1-3 常见的请求消息头消息头说  明示  例Accept可接受的响应内容类型(Content-Types)Accept: text/plainAccept-可接受的字符集Accept-Charset: utf-8CharsetAccept-可接受的响应内容编码方式Accept-Encoding: gzip, EncodingdeflateAccept-可接受的响应内容语言列表Accept-Language: en-USLanguageAuthorizat用于表示HTTP协议中需要认证资源的认证Authorization: Basic ion信息OSdjJGRpbjpvcGVuIANlc2SdDE==Cache-用来指定当前请求中是否使用缓存Cache-Control: no-cacheControlConnectio客户端(浏览器)想要优先使用的连接类Connection: keep-aliven型Cookie向服务器提供CookieCookie: name=value; name2=value2Content-请求正文的长度Content-Length: 348LengthContent-请求正文的MIME类型(用于POST和PUTContent-Type: application/Type请求中)jsonDate发送该消息的日期和时间Date: Dec, 26 Dec 2015 17:30:00 GMTHost服务器的主机名以及使用的端口号Host: www.itbilu.com:80If-Match仅当客户端提供的值与服务器上对应的值If-Match: 相匹配时,才进行对应的操作"9jd00cdj34pss9ejqiw39d82f20d0ikd"If-允许当请求资源未被修改时,返回304 Not If-Modified-Since: Dec, 26 Modified-Modified状态码Dec 2015 17:30:00 GMTSinceIf-None-允许当请求资源未被修改时,返回304 Not If-None-Match: MatchModified状态码"9jd00cdj34pss9ejqiw39d82f20d0ikd"If-仅当资源自某个特定时间以来未被修改If-Unmodified-Since: Dec, Unmodifie时,才发送响应26 Dec 2015 17:30:00 GMTd-SinceOrigin用于发起一个跨域资源共享的请求Origin: http://www.domain.comProxy-用于向代理进行认证的认证信息Proxy-Authorization: Basic AuthorizatIOoDZRgDOi0vcGVuIHNlionNidJi2==User-浏览器的身份标识字符串User-Agent: Mozilla/……Agent常见的响应消息头如表1-4所示。表1-4 常见的响应消息头消息头说  明示  例Allow用于指明资源支持的有效操作Allow: GET, HEADCache-指明该响应使用的缓存机制Cache-Control: max-Controlage=3600Connectio针对该连接所预期的选项Connection: closenContent-响应正文所使用的编码类型Content-Encoding: gzipEncodingContent-响应正文所使用的语言Content-Language: zh-cnLanguageContent-响应正文的长度Content-Length: 348LengthContent-响应正文的MIME类型Content-Type: text/html; Typecharset=utf-8Date消息被发送时的日期和时间Date: Tue, 15 Nov 1994 08:12:31 GMTETag表示资源的当前状态的一个标识符ETag: "737060cd8c284d8af7ad3082f209582d"Expires指定一个时间,超过该时间则认为此响应Expires: Thu, 01 Dec 1994 已经过期16:00:00 GMTLast-所请求资源的最后修改日期Last-Modified: Dec, 26 Dec Modified2015 17:30:00 GMTLocation指向另一个URI,用于在进行重定向、成Location: https://功创建新资源时使用localhost:5001/api/authors/1234Proxy-要求在访问代理时提供身份认证信息Proxy-Authenticate: BasicAuthenticateServer服务器的名称Server: nginx/1.6.3Set-设置HTTP CookieSet-Cookie: UserID=itbilu; CookieMax-Age=3600; Version=1WWW-表示请求应使用的认证方式WWW-Authenticate: BasicAuthenticate除了标准的HTTP消息头外,一些Web应用程序还会添加自定义消息头,用于返回一些描述或备注类的信息。自定义消息头的名称一般以“X-”开头,以此来指明它并不是一个标准的HTTP消息头,例如X-AspNet-Version用于指明当前服务器运行的ASP.NET的版本。1.2.7 状态码HTTP响应状态代码由3个数字组成,用于指明HTTP请求的结果。在状态码后会有一个状态文本,它以文字形式简单描述状态的信息,如200 OK、404 Not Found和500 Internal Server Error等。根据其表述意义,状态码可分为以下5类。● 1xx:信息,服务器收到请求,需要请求方继续执行操作。● 2xx:成功,服务器成功执行客户端所请求的操作。● 3xx:重定向,需要进一步的操作以完成请求。● 4xx:客户端错误,请求包含语法错误或请求内容不正确。● 5xx:服务端错误,服务器在处理请求的过程中发生了错误。状态码以其首位数字表示它所属的类别,而后两位则表示在该类别中具体的信息,表1-5为常见的HTTP状态码。表1-5 常见的HTTP状态码状状态码名描  述态称码200OK请求操作成功执行,并且响应正文中包含预期的资源201Created资源创建成功,响应正文为空202Accepted已接受请求,并成功开始异步执行,但还未处理完成204No 请求的操作成功执行,响应正文为空Content301Moved 请求的资源已被永久移动,响应消息头中应包括资源的新URI,浏Permane览器会自动重定向到新URIntly303See 对当前请求的响应可以在另一个URI上被找到,该URI在当前响应Other的Location消息头中304Not 所请求的资源未修改,客户端可以从缓存中得到该资源;服务器Modified返回此状态码时,消息正文不应包含任何内容(与204 No Content一样)307Temporar服务端不处理客户端的请求,客户端应向另一个URI请求,该URIy 在当前响应的Location消息头中Redirect400Bad 客户端请求存在错误,如语法错误或请求参数有误,服务器无法Request理解401Unauthori当前请求要访问受保护资源,但却未向服务器提供正确的认证信zed息,或并未提供任何认证信息403Forbidde当请求受保护资源时,尽管客户端提供了正确的认证信息,但由n于权限不够,服务器禁止访问该资源404Not 请求的资源不存在Found405Method 请求的资源不支持客户端指定的HTTP请求方法,该响应的消息头Not 中必须包含Allow项,用以表示当前资源能够接受的请求方法列表Allowed406Not 服务器不支持请求中指定的资源表述格式(由Accept消息头指定)Acceptable409Conflict由于和被请求资源的当前状态之间存在冲突,请求无法完成,冲突通常发生于对PUT方法请求的处理412Precondit客户端请求头中指定了一个或多个先决条件,服务器验证这些先ion Failed决条件失败415Unsuppor请求中使用了服务器不支持的资源表述格式(由Content-Type消息ted 头指定)Media Type500Internal 服务器内部错误,无法完成请求Server Error503Service 由于临时的服务器维护或者过载,服务器当前无法处理请求Unavailable1.3 REST最佳实践REST作为一种架构风格,它不是标准,因此并没有一套确定的、公认的规则。尽管REST包含了6个用于指导设计出RESTful系统的约束,但在具体实现时,在很多细节上仍然会有多种多样的方式。不同的实现方式使系统具有不同的表现或不同的使用方式,因此在实现时,应遵循一些基本原则,也即最佳实践。首先,在实现RESTful系统时,应正确地使用HTTP方法、HTTP消息头和HTTP状态码。在上一节我们已经看到,HTTP协议对HTTP方法、消息头、响应码等都有详尽且明确的定义,当设计RESTful API时,应遵循其定义。比如,对于HTTP方法,应使用GET方法获取资源,使用POST方法创建资源。如果没有遵循这些方法的定义,则可能会出现使用POST方法获取、删除资源等情况,这是因为当客户端发送一个POST请求时,服务器上相应的方法不是创建资源,反而是获取或删除资源。同样,客户端与服务端在进行请求与响应时,应正确地使用HTTP消息头。比如,当客户端要想指定资源的预期表述格式时,应使用Accept消息头,而非其他方式,这也正是该消息头的意义所在。当服务器向客户端返回响应时,也应正确地使用HTTP状态码。比如,当操作成功却不需要返回响应正文时,应使用返回204 No Content(删除或更新资源)或201 Created(创建资源)。又如,当服务器不支持客户端指定的资源表述格式时,应返回406 Not Acceptable状态码。由此可以看出,理解HTTP协议并正确地使用它对于设计出规范的RESTful API非常重要。除了这些原则以外,在设计资源的URI时也应注意下列原则。● 使用名词的复数表示一个资源集合,如api.domain.com/users。● 使用斜线“/”用来表示资源之间的层次关系,如

api.domain.com/users/1234/orders。● 对资源的增、删、查、改等操作名称不应包含在URL中,反之应

正确使用HTTP方法。比如,GET /deleteuser/1234(错误),

DELETE users/1234(正确)。● 如果一个操作无法对应到资源的某个操作上,此时可以适当地在

URI中包含动词,但仍然应该基于一个资源的标识符,如下所示。PUT /users/1234/set-adminDELETE /users/1234/set-admin● 查询字符串可以用来对资源进行筛选、搜索或分页查询等操作,

如下所示。GET /users?role=adminGET /users?searchQuery=abcGET /users?pageSize=25&pageNumber=2● URI应使用小写字母。● URI中可以使用中划线“-”来增加其可读性,如下例中使用“-”

来代替空格。 http://api.domain.com/blogs/this-is-my-first-post● URI中不应使用下划线。在浏览器或高级编辑器中,URI通常会

带有下划线,以表示它是可点击的,这个下划线将会使URI中的

下划线不可见,可以使用中划线“-”替代下划线。● URL末尾不应包含斜线“/”,尽管URL末尾包含了“/”并不影响

其功能,然而末尾的“/”没有任何意义甚至还有可能会造成歧

义,因此服务器返回给客户端的URL末尾不应包含“/”。

试读结束[说明:试读内容隐藏了图片]

下载完整电子书


相关推荐

最新文章


© 2020 txtepub下载