什么是RESTful?

REST全稱是Representational State Transfer,中文意思是表述狀態(tài)轉(zhuǎn)移。REST本身并沒有創(chuàng)造新的技術(shù)、組件或服務(wù),而隱藏在RESTful背后的理念就是使用Web的現(xiàn)有特征和能力, 更好地使用現(xiàn)有Web標(biāo)準(zhǔn)中的一些準(zhǔn)則和約束。 如果一個(gè)架構(gòu)符合REST的約束條件和原則,我們就稱它為RESTful架構(gòu)。對(duì)于RESTful,原作者是這樣描述的【我這篇文章的寫作目的,就是想在符合架構(gòu)原理的前提下,理解和評(píng)估以網(wǎng)絡(luò)為基礎(chǔ)的應(yīng)用軟件的架構(gòu)設(shè)計(jì),得到一個(gè)功能強(qiáng)、性能好、適宜通信的架構(gòu)。】

綜合上面的解釋,我們總結(jié)一下什么是RESTful架構(gòu):

  1. 每一個(gè)URI代表一種資源;
  2. 客戶端和服務(wù)器之間,傳遞這種資源的某種表現(xiàn)層;
  3. 客戶端通過四個(gè)HTTP動(dòng)詞,對(duì)服務(wù)器端資源進(jìn)行操作,實(shí)現(xiàn)”表現(xiàn)層狀態(tài)轉(zhuǎn)化”。

什么是Web API?

ASP.NET Web API基于C#構(gòu)建安全的符合REST風(fēng)格的API。通過ASP.NET Web API,可以快速創(chuàng)建在各個(gè)客戶端進(jìn)行調(diào)用的服務(wù),包括Web瀏覽器端和移動(dòng)端等。如下所示:

為什么要用Web API?

ASP.NET Web API是一個(gè)框架,可以很容易構(gòu)建達(dá)成了廣泛的HTTP服務(wù)客戶端,包括瀏覽器和移動(dòng)設(shè)備。是構(gòu)建RESTful應(yīng)用程序的理想平臺(tái)的.NET框架。在系統(tǒng)架構(gòu)中的地位,如下所示:

創(chuàng)建ASP.NET Web API項(xiàng)目

文件–新建–項(xiàng)目 打開【創(chuàng)建新項(xiàng)目】窗口,然后選擇【ASP.NET Web應(yīng)用程序(.NET Framework)】,點(diǎn)擊下一步,如下所示:

進(jìn)入【配置新項(xiàng)目】窗口,輸入項(xiàng)目名稱,選擇項(xiàng)目保存路徑,然后點(diǎn)擊【創(chuàng)建】,如下所示:

進(jìn)入【創(chuàng)建新的ASP.NET Web應(yīng)用程序】創(chuàng)建,選擇【空】,然后添加【MVC,Web API】核心引用,然后點(diǎn)擊【創(chuàng)建】如下所示:

稍等片刻,項(xiàng)目即創(chuàng)建成功,目錄結(jié)構(gòu)如下所示:

創(chuàng)建第一個(gè)接口

在Controllers文件夾,右鍵–添加–Web API控制器類,如下所示:

 通過模板創(chuàng)建的控制器,自動(dòng)添加了示例代碼,且默認(rèn)繼承ApiController,如下所示:

namespace WebApiDemo.Controllers
{
public class StudentController : ApiController
{
// GET api/<controller>
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}

// GET api/<controller>/5
public string Get(int id)
{
return "value";
}

// POST api/<controller>
public void Post([FromBody] string value)
{
}

// PUT api/<controller>/5
public void Put(int id, [FromBody] string value)
{
}

// DELETE api/<controller>/5
public void Delete(int id)
{
}
}
}

定制API

為了進(jìn)行測(cè)試,首先新建Model類Student,如下所示:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WebApiDemo.Models
{
public class Student
{
public int Id { get; set; }

public string Name { get; set; }

public int Age { get; set; }

public bool Sex { get; set; }
}
}

1. GET方式

在StudentController中,引用Models命名空間中的Student模型,修改Get方法,如下所示:

默認(rèn)情況下,WebApi模板自動(dòng)創(chuàng)建了兩個(gè)Get方法,一個(gè)無參,一個(gè)有參,分別返回列表和具體實(shí)例,進(jìn)行調(diào)整,返回Student數(shù)據(jù),如下所示:

// GET api/<controller>
public IEnumerable<Student> Get()
{
return new Student[] { new Student() {
Id=1,
Name="Alan.hsiang",
Age=20,
Sex=true
}, new Student() {
Id=2,
Name="Json.hsiang",
Age=18,
Sex=false
} };
}

// GET api/<controller>/5
public Student Get(int id)
{
return new Student()
{
Id = 1,
Name = "Alan.hsiang",
Age = 20,
Sex = true
};
}

然后運(yùn)行VisualStudio,默認(rèn)端口為44311,通過PostMan進(jìn)行測(cè)試。

不帶參數(shù),返回Student列表。如下所示:

帶參數(shù)的,返回某個(gè)具體的Student實(shí)例,id可以通過api/Controller/id的方式進(jìn)行傳遞。如下所示:

2. POST方式

POST方法主要是通過body表單的方式進(jìn)行提交,本例修改自帶的代碼,接收入?yún)tudent實(shí)例,返回Student字符串,如下所示:

// POST api/<controller>
public string Post([FromBody] Student value)
{
return string.Format("學(xué)生的ID={0},姓名={1},年齡={2},性別={3}",value.Id,value.Name,value.Age,value.Sex);

}

通過Postman,進(jìn)行訪問,訪問方式選擇POST,Body選擇raw,數(shù)據(jù)格式選擇JSON,如下所示:

3. PUT方式

PUT方式一般用于修改數(shù)據(jù),本例為了測(cè)試,返回接收的ID,如下所示:

// PUT api/<controller>/5
public int Put(int id, [FromBody] string value)
{
//為了測(cè)試,返回接收到的id
return id;
}

通過Postman進(jìn)行測(cè)試,請(qǐng)求方式選擇PUT,Body內(nèi)容如果只有一個(gè)string類型參數(shù),則參數(shù)名為空,如下所示:

4. DELETE方式

DELETE方式一般用于刪除數(shù)據(jù),本例為了測(cè)試,返回一個(gè)字符串,如下所示:

// DELETE api/<controller>/5
public string Delete(int id)
{
return string.Format("Id={0} 已刪除", id);
}

通過Postman進(jìn)行測(cè)試,請(qǐng)求方式選擇DELETE,如下所示:

總結(jié)

通過以上示例的測(cè)試,總結(jié)如下:

通過以上總結(jié),發(fā)現(xiàn)WebAPI與RESTful風(fēng)格架構(gòu)不謀而合。

同一方式多個(gè)參數(shù)

在本例中,如果有多個(gè)GET方式的請(qǐng)求方法,且參數(shù)格式,個(gè)數(shù)不同,應(yīng)該如何匹配,如下所示:

// GET api/<controller>
public IEnumerable<Student> Get()
{
return new Student[] { new Student() {
Id=1,
Name="Alan.hsiang",
Age=20,
Sex=true
}, new Student() {
Id=2,
Name="Json.hsiang",
Age=18,
Sex=false
} };
}

// GET api/<controller>/5
public Student Get(int id)
{
return new Student()
{
Id = 1,
Name = "Alan.hsiang",
Age = 20,
Sex = true
};
}

// GET api/<controller>/5?name=aabbcc
public Student Get(int id,string name)
{
return new Student()
{
Id = id,
Name = name,
Age = 22,
Sex = true
};
}

前兩種方式以通過Postman進(jìn)行測(cè)試,現(xiàn)在測(cè)試第三種方式,如下所示:

同一方式,不同名稱 

通過以上示例,可以看出方法名和請(qǐng)求方式是一一對(duì)應(yīng)的,那如果方法名和請(qǐng)求方式不一致呢?

 首先增加GetStudent方式,為了區(qū)分,在返回的Name值分別寫了0和1,如下所示:

// GET api/<controller>/5?name=aabbcc
public Student Get(int id,string name)
{
return new Student()
{
Id = id,
Name = name+"---0",
Age = 22,
Sex = true
};
}

public Student GetStudent(int id, string name)
{
return new Student()
{
Id = id,
Name = name+"---1",
Age = 22,
Sex = true
};
}

打開Postman進(jìn)行測(cè)試,直接報(bào)錯(cuò),稱找到了兩個(gè)符合格式的資源的,如下所示:

以上問題,通過查看WebApiConfig.cs即可發(fā)現(xiàn),WebApi注入的routeTemplate是api/{controller}/{id},沒有action做區(qū)分,此處和MVC不同。WebApi注冊(cè)默認(rèn)路由模板,如下所示:

namespace WebApiDemo
{
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API 配置和服務(wù)

// Web API 路由
config.MapHttpAttributeRoutes();

config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
}

Route特性

為了解決兩個(gè)訪問方式相同,參數(shù)相同,但是方法名不同,會(huì)導(dǎo)致獲取報(bào)錯(cuò)的問題,WepApi引入了路由特性,如下所示:

[Route("api/Student/QueryStudent/{id}")]
[HttpGet]
public Student QueryStudent(int id, string name)
{
return new Student()
{
Id = id,
Name = name + "---1",
Age = 22,
Sex = true
};
}

如下,通過Postman進(jìn)行訪問,則可以正常訪問。默認(rèn)訪問Get(int id,string name)

通過路由特性,訪問/api/Student/QueryStudent/4?name=HEX,如下所示:

路由前綴 

通過路由特性,完美解決了一個(gè)Controller,同一種方式,同時(shí)訪問兩個(gè)不同的方法的問題。但是如果每一個(gè)路由特性都寫全稱,也會(huì)很繁瑣,且容易出錯(cuò),所以路由前綴,應(yīng)運(yùn)而生。

路由前綴修飾Controller,路由特性修飾Action,如下所示:

namespace WebApiDemo.Controllers
{
[RoutePrefix("api/Teacher")]
public class TeacherController : ApiController
{
public string Get(int id, string name) {
return string.Format("[Get]正在查找的老師id={0},姓名={1}", id, name);
}

[Route("query/{id}")]
[HttpGet]
public string QueryTeacher(int id, string name) {
return string.Format("[Query]正在查找的老師id={0},姓名={1}", id, name);
}
}
}

這樣在訪問時(shí),即可區(qū)分,默認(rèn)訪問Get方法,如下所示:

 通過路由特性,訪問Query方法,如下所示:

本文章轉(zhuǎn)載微信公眾號(hào)@老碼識(shí)途

上一篇:

使用Rust語言快速構(gòu)建API能力開放

下一篇:

使用 Node 創(chuàng)建 RESTful API 服務(wù)
#你可能也喜歡這些API文章!

我們有何不同?

API服務(wù)商零注冊(cè)

多API并行試用

數(shù)據(jù)驅(qū)動(dòng)選型,提升決策效率

查看全部API→
??

熱門場(chǎng)景實(shí)測(cè),選對(duì)API

#AI文本生成大模型API

對(duì)比大模型API的內(nèi)容創(chuàng)意新穎性、情感共鳴力、商業(yè)轉(zhuǎn)化潛力

25個(gè)渠道
一鍵對(duì)比試用API 限時(shí)免費(fèi)

#AI深度推理大模型API

對(duì)比大模型API的邏輯推理準(zhǔn)確性、分析深度、可視化建議合理性

10個(gè)渠道
一鍵對(duì)比試用API 限時(shí)免費(fèi)