WEB API系列(一):WEB API的适用场景、第一个实例
在我前一篇博客《WebAPI前置知识:HTTP与RestfulAPI》中已经给各位简单介绍了HTTP协议与RestFul API的关系,以及一些基本的HTTP协议知识,在这些知识的铺垫下,今天,我们一起来讨论一下WEB API的适用场景,然后写我们第一个WEB API接口,并演示如何对其进行简单调用。
很多人都很迷惑,既然有了WCF为什么还要有WEB API?WEB API会不会取代WCF?
就我的看法,WCF提供的是一种RPC实现的集合,WCF的设计更多地考虑了SOA的场景,以及各种RPC的问题。很多人也会说,RestFul API也是一种RPC啊,并且WCF中也有关于RestFul 的实现啊。很多资料中RPC和RestFul在风格概念上是有一些区别的,其实我觉得这两者的区别比较主观,过度纠结这些就学院派了;我主要关注了实际使用上的一些问题,在WCF中,支持的协议很多,WS-*系列协议,以及一些更简洁的协议,其中提供了一些专用通信协议的性能是非常高的,并且WCF还提供了服务发现等功能,我认为WCF更适合内部系统间的高性能调用,社区中也有其他一些RPC方案可以选择,例如gRPC,Avor,thrift都是和WCF定位相同的产品;而WEB API是关注于HTTP RestFul风格的产品,在此基础上,任何语言、任何终端都能非常容易地进行对接,并且能利用非常成熟的各种HTTP基础设施和解决方案来进行开发、调试、负载均衡、内容分发。所以,WEB API是一种针对HTTP的,偏重于快速开发RestFul风格开放式API的开发框架。目前看来,他并不能取代WCF,他们各有适合的场景,不能认为WEB API是WCF的替代产品。
OK,现在我们来开发第一组WEB API接口!使用VS2012以后的版本都有现成的WEB API创建模板,大家跟着创建就好了,创建出来后,项目中会有MVC、WEB API的项目,WEB API对MVC有依赖,不能单独创建!而WEB API和MVC都是利用类似的路由机制,所以在默认路由中,WEB API 使用
/api/{controller}/{id}
作为路由,添加了/api/节以区分MVC和web api。
接下来,我们添加一个WEB API的Controller,取名为PersonController,他继承于ApiController;在创建这个Controller的时候,我们就定义了一种资源:Person,在PersonController里的所有操作均围绕着Person这个资源来的。接下来我们开始定义一组增删改查操作。
在Web API中,默认路由采用了一种约定:根据谓词来进行路由,而方法名的前缀就是调用该方法对应使用的HTTP谓词。代码示例如下:
/// <summary>/// Person 为资源,对Person进行的一组操作/// </summary>public class PersonController : ApiController { private static List<Person> _personLst = new List<Person>(); /// <summary>/// 获取一个Person /// </summary>/// <param name="id">Person的ID</param>/// <returns>Person</returns>public Person GetPerson(long id) { return _personLst.Find(x => x.Id == id); } /// <summary>/// 添加一个Person /// </summary>/// <param name="person">Person</param>public void PostAddPerson(Person person) { _personLst.Add(person); } /// <summary>/// 修改一个 /// </summary>/// <param name="id">Person Id</param>/// <param name="person">新</param>public void PutModifyPerson(long id, Person person) { var p = _personLst.Find(x => x.Id == id); p.Age = person.Age; p.Name = person.Name; p.Sex = person.Sex; } /// <summary>/// 删除一个Person /// </summary>/// <param name="id">Person ID</param>public void DeletePerson(long id) { _personLst.RemoveAll(x => x.Id == id); } }
一个简单的针对资源的CRUD操作的API就好了,不用解析输入,不用拼接输出,就是那么简单!让我们来遛一遛!
发送请求:谓词为POST,语义创建Person,Person描述在Body里,head中声明了Body通过Json序列化。
收到响应:响应码204,属于2XX类型执行成功,Body里没有数据
发送请求:谓词为GET,语义为查询Person资源,Id为1的,head中声明希望接收使用XML序列化的数据
收到响应:响应码为200,执行成功,Body中有数据,数据使用XML序列化
发送请求:谓词为PUT,语义为修改ID为1的Person资源,修改内容在Body中,Content-Type标明Body使用Json序列化,在Body中我们将Name修改为Test1Changed
收到响应,响应码为204,执行成功
发送请求:谓词为GET,语义为查询ID为1的Person资源,Accept标明希望接收到Json数据
收到响应:可以看到Body为使用Json序列化的内容,Name属性已经变更为Test1Changed
发送请求:谓词为DELETE,语义为删除ID为1的Person资源
收到响应:响应码204,执行成功
发送请求:谓词为GET,语义为查询ID为1的Person资源,Accept标明希望接收到Json数据
收到响应:响应码为200,执行成功,响应内容为null,资源已删除
这就是我用Fiddler来发送、调用的一组RestFul接口,大家可以看到,整个调用过程使用到了HTTP的语义,用到了谓词路由、内容协商。在增、删、改操作中,我都是使用void作为返回值,根据HTTP Code 判断,大家也可以自定义一些返回数据来做出更进一步的操作描述。
在写了这些API后,我们需要在程序中调用,我以C#为例写一组对这些接口调用的实现。在C#中,传统调用HTTP接口一般有两种办法: WebRequest/WebResponse组合的方法调用和WebClient类进行调用。第一种方法抽象程度较低,使用较为繁琐;而WebClient主要面向了WEB网页场景,在模拟Web操作时使用较为方便,但用在RestFul场景下却比较麻烦,在Web API发布的同时,.NET提供了两个程序集:System.Net.Http和System.Net.Http.Formatting。这两个程序集中最核心的类是HttpClient。在.NET4.5中带有这两个程序集,而.NET4需要到Nuget里下载Microsoft.Net.Http和Microsoft.AspNet.WebApi.Client这两个包才能使用这个类,更低的.NET版本就只能表示遗憾了只能用WebRequest/WebResponse或者WebClient来调用这些API了。
在使用中,System.Net.Http这个程序集提供了HttpClient类以及相关的HTTP调用,而System.Net.Http.Formatting提供了一些针对HttpClient的帮助扩展,更好地支持了内容协商、Content创建等功能。下面我就和大家一起写一下这个例子:
我们新建一个控制台程序:
代码如下:
public class Person { public long Id { get; set; } public string Name { get; set; } public int Age { get; set; } public string Sex { get; set; } public override string ToString() { return $"Id={Id} Name={Name} Age={Age} Sex={Sex}"; } } class Program { static void Main(string[] args) { var client = new HttpClient(); client.BaseAddress = new Uri("http://localhost:22658/"); //基本的API URL client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); //默认希望响应使用Json序列化 Run(client); Console.ReadLine(); } static async void Run(HttpClient client) { var result = await AddPerson(client); Console.WriteLine($"添加结果:{result}"); //添加结果:truevar person = await GetPerson(client); Console.WriteLine($"查询结果:{person}"); //查询结果:Id=1 Name=test Age=10 Sex=F result = await PutPerson(client); Console.WriteLine($"更新结果:{result}"); //更新结果:true result = await DeletePerson(client); Console.WriteLine($"删除结果:{result}"); //删除结果:true } static async Task<bool> AddPerson(HttpClient client) { return await client.PostAsJsonAsync("api/Person", new Person() { Age = 10, Id = 1, Name = "test", Sex = "F" }) //向Person发送POST请求,Body使用Json进行序列化 .ContinueWith(x => x.Result.IsSuccessStatusCode); //返回请求是否执行成功,即HTTP Code是否为2XX } static async Task<Person> GetPerson(HttpClient client) { return await await client.GetAsync("api/Person/1") //向Person发送GET请求 .ContinueWith(x => x.Result.Content.ReadAsAsync<Person>( //获取返回Body,并根据返回的Content-Type自动匹配格式化器反序列化Bodynew List<MediaTypeFormatter>() {new JsonMediaTypeFormatter()/*这是Json的格式化器*/ ,new XmlMediaTypeFormatter()/*这是XML的格式化器*/})); } static async Task<bool> PutPerson(HttpClient client) { return await client.PutAsJsonAsync("api/Person/1", new Person() { Age = 10, Id = 1, Name = "test1Change", Sex = "F" }) //向Person发送PUT请求,Body使用Json进行序列化 .ContinueWith(x => x.Result.IsSuccessStatusCode); //返回请求是否执行成功,即HTTP Code是否为2XX } static async Task<bool> DeletePerson(HttpClient client) { return await client.DeleteAsync("api/Person/1") //向Person发送DELETE请求 .ContinueWith(x => x.Result.IsSuccessStatusCode); //返回请求是否执行成功,即HTTP Code是否为2XX } }
这就完成了这组API的调用,是不是非常简单方便?HTTPClient使用全异步的方法,并且他有良好的扩展性,我会在之后的博客中再聊这个问题。
OK,到此为止一组简单的Restful API和C#的调用客户端就完成了,但这只是开始,Web API是一个很强大的框架,他的扩展点非常丰富,这些扩展能为我们的开发提供很多的帮助,下一篇博文我将为大家带来WEB API中Filter的使用。
博文中如有不正确的地方欢迎大家指正。
原文地址:http://www.cnblogs.com/UliiAn/p/5373854.html
.NET社区新闻,深度好文,微信中搜索dotNET跨平台或扫描二维码关注
WEB API系列(一):WEB API的适用场景、第一个实例相关推荐
- maven mybatis mysql_Java Web学习系列——Maven Web项目中集成使用Spring、MyBatis实现对MySQL的数据访问...
标签: 本篇内容还是建立在上一篇Java Web学习系列--Maven Web项目中集成使用Spring基础之上,对之前的Maven Web项目进行升级改造,实现对MySQL的数据访问. 添加依赖Ja ...
- java date加一天_Java日期时间API系列15-----Jdk8中API类,java日期计算2,年月日时分秒的加减等...
通过Java日期时间API系列8-----Jdk8中java.time包中的新的日期时间API类的LocalDate源码分析 ,可以看出java8设计非常好,实现接口Temporal, Tempora ...
- 适合0基础的web开发系列教程-web 存储
HTML5 web 存储,一个比cookie更好的本地存储方式. 什么是 HTML5 Web 存储? 使用HTML5可以在本地存储用户的浏览数据. 早些时候,本地存储使用的是 cookie.但是Web ...
- [Web Chart系列之一]Web端图形绘制SVG,VML, HTML5 Canvas 技术比较
先介绍一下矢量图的概念: 矢量图使用直线和曲线来描述图形,这些图形的元素是一些点.线.矩形.多边形.圆和弧线等等,它们都是通过数学公式计算获得的.例如一幅花的矢量图形实际上是由线段形成外框轮廓,由外框 ...
- [Web Chart系列之一(续)]Web端图形绘制SVG,VML, HTML5 Canvas 简单实例
前言 本篇是继 [Web Chart系列之一]Web端图形绘制SVG,VML, HTML5 Canvas 技术比较 的补充和实例说明各种技术的使用方式. VML 的用法和实例 引入命名空间之后,就可以 ...
- 玩 High API 系列好文(一):智能客服、钉钉Ding功能、智能云相册、快速实现身份验证
云栖君导读:通过本系列文章,您可以快速了解每个API提供的功能及适用的场景,帮助您快速查找到满足特定功能的API.您也可以通过对多个API进行编排组合,来轻松完成一项应用创新. 一. 玩 High A ...
- Web API系列(三)统一异常处理
前面讲了webapi的安全验证和参数安全,不清楚的朋友,可以看看前面的文章,<Web API系列(二)接口安全和参数校验>,本文主要介绍Web API异常结果的处理.作为内部或者是对外提供 ...
- WEB API 系列(二) Filter的使用以及执行顺序
在WEB Api中,引入了面向切面编程(AOP)的思想,在某些特定的位置可以插入特定的Filter进行过程拦截处理.引入了这一机制可以更好地践行DRY(Don't Repeat Yourself)思想 ...
- Web API系列之三 基本功能实现
Web API系列之二讲解了如何搭建一个WebApi的基架,本文主要在其基础之上实现基本的功能.下面开始逐步操作: 一.配置WebApi的路由-用于配置外部如何访问内部资源的url的规则 1.添加Gl ...
- Web API系列(三):添加接口详细说明及测试
1.引言 前边两篇博客介绍了Web API的基本框架以及路由配置,这篇博客主要解决在前后端分离项目中,为前端人员提供详细接口说明的问题,主要是通过修改WebApi HelpPage相关代码和添加Web ...
最新文章
- Float构建三栏DIV CSS网页布局
- 115.什么是SHELL
- nodejs 实践:express 最佳实践(六) express 自省获得所有的路由
- VMware 安装LINUX系统(一)
- w10计算机字体怎么设置在哪里设置,win10系统电脑字体设置的操作方法
- soapUI接口测试工具
- 从0开始,如何设计一个社交电商产品
- vue-waterfall2瀑布流使用及坑
- 爬取初试----猫眼电影,猫眼评分
- python上下对齐_python-docx设置表格对齐方式
- 银河麒麟服务器系统使用的一些问题和解决方案
- 常用计算机软件不包括什么,大学计算机基础试题及答案(二)
- Docker安装配置Jenkins教程
- js逆向,破解企名片网站的加密参数
- 【笨嘴拙舌WINDOWS】实践检验之按键精灵【Delphi】
- idea右边依赖爆红的解决方案
- mysql索引最左前缀原则
- 计算机毕业设计SSM车站商铺信息管理系统【附源码数据库】
- Patroni的pause和resume功能
- 浅绛彩瓷的行情与收藏