• http
  • 无状态API

rest api

REST为客户端到服务器的请求定义了一组固定的操作GET,POST,PUT和DELETE。每个请求都将通过包含有效负载(通常为JSON)的响应来回答。请求包含在查询本身中的参数,或者在它是POST请求时包含为有效负载(通常为JSON)的参数。

  • 有一个称为RESTful API的标准,它定义了以下规则(您实际上不必使用它):
    • GET用于检索资源
    • PUT用于更改资源状态
    • POST用于创建资源
    • DELETE用于删除资源

ReFit

ReFit不能替代REST。相反,它建立在REST之上,并允许我们像调用简单方法一样调用服务器端点。这是通过在客户端和服务器之间共享接口来实现的。在服务器端,您的控制器将实现一个接口

  1. public interface IMyEmployeeApi
  2. {
  3. [Get("/employee/{id}")]
  4. Task<Employee> GetEmployee(string id);
  5. }

然后,在客户端,您需要包括相同的接口并使用以下代码:

  1. var api = RestService.For<IMyEmployeeApi>("https://www.myserver.com");
  2. var employee = await api.GetEmployee("abc");

就这么简单。除了几个NuGet软件包外,无需运行困难的自动化程序或使用任何第三方工具。

这更接近最佳方案。现在,我们有了IntelliSense,并且客户端和服务器之间的合同很牢固。但是还有另一种选择,在某些方面甚至更好。

昂首阔步

像ReFit一样,Swagger也建立在REST之上。OpenAPI[2]或Swagger是REST API的规范。它描述了具有简单JSON文件的REST Web服务。这些文件是Web服务的API架构。它们包括:

该JSON文件实质上是客户端和服务器之间的合同。这是一个描述一个称为Swagger Petstore[3]的Web服务的swagger文件的示例(为清楚起见,我删除了一些部分):

  1. {
  2. "swagger":"2.0",
  3. "info":{
  4. "version":"1.0.0",
  5. "title":"Swagger Petstore",
  6. "description":"A sample API that uses a petstore as an example to demonstrate features in the swagger-2.0 specification",
  7. },
  8. "host":"petstore.swagger.io",
  9. "basePath":"/api",
  10. "schemes":[
  11. "http"
  12. ],
  13. "consumes":[
  14. "application/json"
  15. ],
  16. "produces":[
  17. "application/json"
  18. ],
  19. "paths":{
  20. "/pets":{
  21. "get":{
  22. "description":"Returns all pets from the system that the user has access to",
  23. "operationId":"findPets",
  24. "produces":[
  25. "application/json",
  26. "application/xml",
  27. ],
  28. "parameters":[
  29. {
  30. "name":"tags",
  31. "in":"query",
  32. "description":"tags to filter by",
  33. "required":false,
  34. "type":"array",
  35. "items":{
  36. "type":"string"
  37. },
  38. "collectionFormat":"csv"
  39. },
  40. {
  41. "name":"limit",
  42. "in":"query",
  43. "description":"maximum number of results to return",
  44. "required":false,
  45. "type":"integer",
  46. "format":"int32"
  47. }
  48. ],
  49. "responses":{
  50. "200":{
  51. "description":"pet response",
  52. "schema":{
  53. "type":"array",
  54. "items":{
  55. "$ref":"#/definitions/Pet"
  56. }
  57. }
  58. },

让我们考虑一下这个结果。使用上面的JSON文件,您可以潜在地创建具有完整IntelliSense的C#客户端。毕竟,您知道所有路径,操作,它们期望的参数,什么参数类型,什么是响应等等。

有几种工具可以做到这一点。对于服务器端,可以使用Swashbuckle.AspNetCore[4]将Swagger添加到ASP.NET中并生成所述JSON文件。对于客户端,您可以使用swagger-codegen[5]和AutoRest[6]来使用这些JSON文件并生成客户端。让我们看一个如何做到这一点的例子:

将Swagger添加到ASP.NET服务器

  • 首先添加NuGet包Swashbuckle.AspNetCore[7]。在中ConfigureServices,注册Swagger生成器:
  1. services.AddSwaggerGen(options =>
  2. options.SwaggerDoc("v1", new OpenApiInfo {Title = "My Web API", Version = "v1"}));
  • 在添加Configure方法中Startup.cs:
  1. app.UseSwagger();
  • 最后,控制器内部的动作应使用[HttpXXX]和[FromXXX]属性修饰:
  1. [HttpPost]
  2. public async Task AddEmployee([FromBody]Employee employee)
  3. {
  4. //...
  5. }
  6. [HttpGet]
  7. public async Task<Employee> Employee([FromQuery]string id)
  8. {
  9. //...
  10. }

就像服务器端一样简单。运行项目时,swagger.json将生成一个文件,可用于生成客户端

使用AutoRest从Swagger生成客户端

要开始使用AutoRest[8],与安装NPM[9]:npm install -g autorest。安装后,您将需要使用AutoRest的命令行界面从该swagger.json文件生成C#客户端。这是一个例子:

  1. autorest --input-file="./swagger.json" --output-folder="GeneratedClient" --namespace="MyClient" --override-client-name="MyClient" --csharp

这将产生一个GeneratedClient包含生成的C#文件的文件夹。请注意,名称空间和客户端名称被覆盖。从这里,将此文件夹添加到Visual Studio中的客户端项目。

REST - 图1

您需要安装Microsoft.Rest.ClientRuntimeNuGet软件包,因为生成的代码取决于该软件包。安装后,您可以像使用常规C#类一样使用API:

  1. var client = new MyClient();
  2. Employee employee = client.Employee(id: "abc");

您可以在AutoRest的文档中[10]阅读一些细微之处。而且您需要使该过程自动化,因此我建议阅读Patrik Svensson的教程,[11]以获得一些好的建议以及Peter Jausovec的这篇文章[12]。

Swagger的问题是JSON文件是在运行时创建的,因此这使得在CI / CD流程中实现自动化有点困难。

传统REST vs Swagger vs ReFit

进行选择时,请注意以下几点。

  • 如果您有一个非常简单的私有REST API,则也许不必理会客户端生成和共享接口。小任务并不能证明付出额外的努力是合理的。
  • Swagger支持多种语言,而ReFit仅支持.NET。Swagger还是许多工具,测试,自动化和UI工具的基础。如果您要创建一个大型的公共API,它将可能是最佳选择。
  • Swagger比ReFit复杂得多。使用ReFit,只需在服务器和客户端项目中添加一个接口即可。另一方面,使用ReFit,您必须为每个控制器创建新的接口,而Swagger会自动进行处理。

但是在决定任何事情之前,请检查与REST无关的第四个选项。gRPC