创建一个可扩展的Web API架构

在开发Web API时,经常会遇到需要处理多种操作的情况。随着时间的推移,这些操作可能会不断增加。为了避免在控制器中添加大量的操作,可以使用一种可扩展的架构。这样,只需要添加新的操作类型即可。本文将介绍如何使用Visual Studio 2017的Web API 2项目模板,结合Autofac,创建一个简单的、可扩展的Web API架构。

架构概述

整个项目结构非常简单。创建了一个名为OperationsController的API控制器,它包含一个名为Process的操作。为了实现操作的可扩展性,定义了一个IOperation接口,所有的操作都必须实现这个接口。此外,还提供了一个名为OperationBase的基类,用于处理一些通用的代码。

代码实现

首先,定义了IOperation接口,如下所示:

public interface IOperation { string Name { get; } string Description { get; } Type ParameterClassType { get; } object Execute(object prm); }

在这个接口中,ParameterClassType属性用于指定执行方法所需的参数对象类型。这个类型用于解析请求体中的JSON数据。如果Execute方法返回非空值,则将其作为结果返回给调用者;否则,返回一个Ok响应。

接下来,定义了OperationsController控制器及其Process操作,如下所示:

public class OperationsController : ApiController { private readonly List _supportedOperations; public OperationsController(IEnumerable supportedOperations) { _supportedOperations = new List(supportedOperations); } [HttpPost] public async Task Process(string operationName) { IOperation operation = _supportedOperations.FirstOrDefault(x => x.Name == operationName); if (operation == null) return BadRequest($"'{operationName}' is not supported."); string jsonBody = await Request.Content.ReadAsStringAsync(); object operationParams = null; try { if (operation.ParameterClassType != null) operationParams = Newtonsoft.Json.JsonConvert.DeserializeObject(jsonBody, operation.ParameterClassType); object result = operation.Execute(operationParams); if (result != null) return Json(result); } catch (Exception ex) { return InternalServerError(ex); } return Ok(); } }

在这个控制器中,通过构造函数注入实现了操作的注入。Process操作接受一个操作名称,并从请求体中读取操作参数。然后,它找到相应的操作并执行它。如果操作返回结果,则将结果作为JSON返回;否则,返回一个Ok响应。

路由配置如下所示:

config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{operationName}", defaults: new { controller = "operations", action = "process", operationName = "help" } );

这个路由配置将所有请求路由到OperationsControllerProcess操作。如果没有提供操作名称,则执行help操作。

Autofac依赖注入配置如下所示:

ContainerBuilder builder = new ContainerBuilder(); builder.RegisterApiControllers(Assembly.GetExecutingAssembly()); builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()) .Where(t => t.IsAssignableTo()) .As(); var container = builder.Build(); config.DependencyResolver = new AutofacWebApiDependencyResolver(container);

在这个配置中,注册了控制器和所有实现了IOperation接口的操作。然后,将Autofac容器设置为Web API管道的依赖解析器。

使用Postman进行测试

可以使用Postman来测试这个Web API。首先,测试没有参数的help操作。然后,测试需要参数的sum操作。

为了演示这个想法,只提供了一个简单的实现。在实际应用中,应该将命令处理操作与控制器类分离。此外,应该提供更详细的操作信息,例如操作是否需要参数以及参数的类型和名称。由于操作不是控制器动作,Swagger无法提供参数信息。

此外,还没有实现自动验证。可以在Execute方法之前进行验证,或者每个操作可以执行自己的验证逻辑。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485