In my previous blog, I have given you a brief introduction to the relationship between HTTP protocol and RestFul API, as well as some basic HTTP protocol knowledge. Based on this knowledge, today, let’s come together Discuss the applicable scenarios of WEB API, then write our first WEB API interface and demonstrate how to make a simple call to it.
Many people are confused. Why do we need WEB API now that we have WCF? Will WEB API replace WCF?
In my opinion, WCF provides a collection of RPC implementations. The design of WCF takes more into account SOA scenarios and various RPC issues. Many people will also say that the RestFul API is also a kind of RPC, and there is also an implementation of RestFul in WCF. In many materials, there are some differences in style concepts between RPC and RestFul. In fact, I think the difference between the two is more subjective, and overly entangled in these is academic; I mainly focus on some issues in actual use. In WCF, There are many supported protocols, including the WS-* series protocols, as well as some more concise protocols, which provide some dedicated communication protocols with very high performance, and WCF also provides service discovery and other functions. I think WCF is more suitable for internal systems. For high-performance calls, there are also other RPC solutions in the community to choose from, such as gRPC, Avor, and thrift, which are all products with the same positioning as WCF; and WEB API is a product focusing on HTTP RestFul style. On this basis, any language, Any terminal can be easily connected, and can utilize various very mature HTTP infrastructure and solutions for development, debugging, load balancing, and content distribution. Therefore, WEB API is a development framework for HTTP that focuses on the rapid development of RestFul-style open APIs. At present, it seems that it cannot replace WCF. They each have their own suitable scenarios, and WEB API cannot be considered a substitute for WCF.
OK, now let’s develop the first set of WEB API interfaces! Versions using VS2012 and later have ready-made WEB API creation templates. You can just follow the creation. After creation, there will be MVC and WEB API projects in the project. The WEB API depends on MVC and cannot be created separately! Both WEB API and MVC use similar routing mechanisms, so in the default route, WEB API uses
/api/{controller}/{id}
as the route, adding / api/section to differentiate between MVC and web api.
Next, we add a WEB API Controller, named PersonController, which inherits from ApiController; when creating this Controller, we define a resource: Person, all operations in PersonController They all revolve around the resource Person. Next we start to define a set of add, delete, modify and check operations.
In Web API, the default routing adopts a convention: routing is based on predicates, and the prefix of the method name is the HTTP predicate used to call the method. The code example is as follows:
/// <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); } }
A simple API for CRUD operations on resources is enough, without parsing the input. No need to splice output, it’s that simple! Let’s take a walk!
Send a request: the predicate is POST, the semantics is to create a Person, the Person is described in the Body, and the Head declares that the Body is serialized through Json.
Response received: response code 204, belonging to 2XX type, execution successful, no data in the Body
Send request: predicate is GET, semantics is query Person Resource, with ID 1, declares in the head that it hopes to receive data serialized using XML
Response received: response code is 200, execution is successful, there is data in the Body, and the data is serialized using XML
Send a request: the predicate is PUT, the semantics is to modify the Person resource with ID 1, the modified content is in the Body, the Content-Type indicates that the Body uses Json serialization, in the Body we put the Name Modified to Test1Changed
Received response, response code is 204, execution is successful
Send request: predicate is GET, semantics is query Person with ID 1 Resource, Accept indicates that it hopes to receive Json data
Response received: You can see that the Body is the content serialized using Json, and the Name attribute has been changed to Test1Changed
Send request: The predicate is DELETE, and the semantics is to delete the Person resource with ID 1
Received response: response code 204, execution successful
发送请求:谓词为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}"); //添加结果:true var 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自动匹配格式化器反序列化Body new 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的使用。
博文中如有不正确的地方欢迎大家指正。
The above is the detailed content of The first example of the applicable scenario of ASP.NET WEB API. For more information, please follow other related articles on the PHP Chinese website!