web APIS

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 URLclient.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=Fresult = await PutPerson(client);Console.WriteLine($"更新结果:{result}"); //更新结果:trueresult = 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}}

转载于:https://www.cnblogs.com/fs-4394/p/9981312.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/412795.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

dubbo 整合 zipkin,最简单的方式,亲测有效

大家好&#xff0c;我是烤鸭。 之前也试过网上很多版本&#xff0c;看了好多文章。现在分享最简单的方式&#xff0c;代码侵入性最小的。 1. 修改pom,引入jar。 <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc --> <dependency><…

[Network Architecture]DPN(Dual Path Network)算法详解(转)

https://blog.csdn.net/u014380165/article/details/75676216 论文&#xff1a;Dual Path Networks 论文链接&#xff1a;https://arxiv.org/abs/1707.01629 代码&#xff1a;https://github.com/cypw/DPNs MXNet框架下可训练模型的DPN代码&#xff1a;https://github.com/m…

javax.script.ScriptException: ReferenceError: xxx is not defined in eval

大家好&#xff0c;我是烤鸭&#xff1a; 今天使用 javax.script.ScriptEngine 遇到一个奇怪的问题&#xff0c;无法识别js方法。 1. 报错内容&#xff1a; javax.script.ScriptException: ReferenceError: "a" is not defined in <eval> at line number…

Python的特殊成员

Python 用下划线作为变量前缀和后缀指定特殊变量 _xxx 不能用’from module import *’导入 __xxx__ 系统定义名字 __xxx 类中的私有变量名 核心风格&#xff1a;避免用下划线作为变量名的开始。 现在我们来总结下所有的系统定义属性和方法&#xff0c; 先来看下保留属性&#…

java 实现 常见排序算法(四)基数排序

大家好&#xff0c;我是烤鸭&#xff1a; 今天分享一下基础排序算法之基数排序。 1. 基数排序&#xff1a; 原理&#xff1a;基数排序&#xff08;radix sort&#xff09;属于“分配式排序”&#xff08;distribution sort&#xff09;&#xff0c;又称“桶子法”&#…

今天分享一下做支付宝小程序遇到的坑。ISV权限不足,建议在开发者中心检查对应功能是否已经添加。验签出错,建议检查签名字符串或签名私钥与应用公钥是否匹配

大家好&#xff0c;我是烤鸭&#xff1a; 今天分享一下做支付宝小程序遇到的坑。pom版本 <!-- https://mvnrepository.com/artifact/com.alipay.sdk/alipay-sdk-java --><dependency><groupId>com.alipay.sdk</groupId><artifactId>alipay-sdk-j…

Will not attempt to authenticate using SASL | dubbo项目启动特别慢,拉取 zookeeper 服务日志打印特别慢

大家好&#xff0c;我是烤鸭&#xff1a; 今天分享一下使用dubbo遇到的几个问题。 1. cause: KeeperErrorCode ConnectionLoss for /dubbo/ xxx 异常如下&#xff1a; pid9965&qos.accept.foreign.ipfalse&qos.enabletrue&qos.port10887&timestamp1567…

redis集群搭建【简版】

大家好&#xff0c;我是烤鸭&#xff1a; 今天分享一下redis集群安装&#xff0c;写的比较简单&#xff0c;就是做个记录。 1. 下载&安装 wget http://download.redis.io/releases/redis-5.0.4.tar.gz tar -zxvf redis-5.0.4.tar.gz 解压并编译 https://redis.io/ 2.…

x-shell 通过堡垒机连接 ssh多个机器 自动化脚本

大家好&#xff0c;我是烤鸭&#xff1a; 1. 连接vpn 这一步就没什么说的了。我们用的easyconnect。登录后弹出堡垒机页面。 easyconnect 官网&#xff1a;https://sslvpn.zjweu.edu.cn/com/installClient.html 2. 登录堡垒机账号 登录堡垒机之后&#xff0c;如图&#xff…

javax.mail.MessagingException: while sending message;Connection reset by peer: socket write error

大家好&#xff0c;我是烤鸭&#xff1a; 阿里云邮件推送服务报错。当你也使用阿里云的邮件推送服务提示上面这个错误的话&#xff0c;我先告诉你原因和目前能想到的解决方案。 解决思路&#xff1a; 1. 换企业邮箱&#xff0c;阿里的上限15M&#xff0c;网易的不知道&…

李晓菁201771010114《面向对象程序设计(java)》第十三周学习总结

理论知识&#xff1a;事件处理 1.事件源&#xff1a;能够产生事件的对象都可以成为事件源&#xff0c;如文本框&#xff0c;按钮等。一个事件源是一个能够注册监听器并向监听器发送事件对象的对象。 2.事件监听器&#xff1a;事件监听器对象接收事件源发送的通告&#xff08;事…

记一次 OOM 的原因和处理 出现大量 close_wait,项目无法访问 activeMq和 poi 出现的 OOM

大家好&#xff0c;我是烤鸭: 记一次项目无法访问的事件和处理。由于某个模块每隔几天就会出现无法访问&#xff0c;目前的最简单粗暴的方法就是重启。 1. 现象 项目内日志打印正常&#xff0c;经过dubbo的rpc服务和接口调用正常。http接口无法访问。提示nginx 502。 2.…

谷歌浏览器中安装JsonView扩展程序

实际开发工作中经常用到json数据&#xff0c;那么就会有这样一个需求&#xff1a;在谷歌浏览器中访问URL地址返回的json数据能否按照json格式展现出来。 比如&#xff0c;在谷歌浏览器中访问&#xff1a;http://jsonview.com/example.json 展现效果如下&#xff1a; 那么安装了…

Serialized class com.xxx.xxxService must implement java.io.Serializable

大家好&#xff0c;我是烤鸭&#xff1a; 使用dubbo的时候&#xff0c;遇到如下的问题。 Serialized class com.xxx.xxxService must implement java.io.Serializable 1. 异常 dubbo无论使用哪个协议传递参数的时候&#xff0c;都需要参数实现序列化接口。 所以提示这个…

CS229 7.1应用机器学习中的一些技巧

本文所讲述的是怎么样去在实践中更好的应用机器学习算法&#xff0c;比如如下经验风险最小化问题&#xff1a; 当求解最优的 后&#xff0c;发现他的预测误差非常之大&#xff0c;接下来如何处理来使得当前的误差尽可能的小呢&#xff1f;这里给出以下几个选项&#xff0c;下面…

8号团队-团队任务三:每日立会(2018-11-27)

团队信息&#xff1a; 1.团队序号 8 2.开发软件 飞机大战 3.今日整理人&#xff1a;徐浩茗 职位&#xff1a;项目经理 学号&#xff1a;2016035107247 4.本次团队会议共有8人参加 无缺席 团队汇报&#xff1a; &#xff08;截图&#xff09;如下 . 4.燃尽图 5.本次会议中遇…

Alibaba 开源工具 Arthas 使用

大家好&#xff0c;我是烤鸭&#xff1a; 很长时间没更新了&#xff0c;最近太忙了&#xff0c;只能抽空水点文章了&#xff0c;今天给大家介绍的是阿里的开源工具 Arthas 的使用。 1. 开源地址 Arthas 是Alibaba开源的Java诊断工具 https://github.com/alibaba/arthas 中文说…

Password

题目 题解 由打表得对于任意\(i \geq 1\)&#xff0c;都有第\(i1\)行和第\(i3\)行相等、 于是我们可以分块维护一下。 然后做完了。 代码 #include <iostream> #include <cstdlib> #include <cstdio> #include <cstring> #include <algorithm>us…

[maven] springboot将jar包打包到指定目录

大家好&#xff0c;我是烤鸭&#xff1a; 今天分享一下springboot将jar包打包到指定目录下。 由于之前上线都是一个打包到一个jar&#xff0c;由于服务多了&#xff0c;1个包100多M&#xff0c;哪怕是小版本上线都需要重新上传jar包。 1.目的 将不常用的比如spring,druid等不常…

springboot启动后卡住 无日志的几种情况

大家好&#xff0c;我是烤鸭&#xff1a; 今天分享一下springboot启动后无日志的问题。 1.场景复现 springboot项目启动后卡住无日志&#xff0c;肯定是报错了或者其他原因&#xff0c;并且日志没有打印出来。 1.1 说一下比较通用常见的场景。 检查一下 是否 exc…