在Sitecore8.2解决方案中使用Swagger作为API管理工具
假设您的Sitecore解决方案需要一些API服务。显而易见的是使用.net Web API实现它们。有时,在构建消费应用程序时,理解API的各种方法对开发人员来说可能是一项挑战。
假设您的Sitecore解决方案需要一些API服务。显而易见的是使用.net Web API实现它们。有时,在构建消费应用程序时,理解API的各种方法对开发人员来说可能是一项挑战。Swagger 是RESTful API的机器可读表示, 支持交互式文档,客户端SDK生成和可发现性。
使用Swagger
使用Swagger为Web API生成良好的文档和帮助页面就像添加NuGet包一样简单。
只要Sitecore仍然是一个asp.net应用程序,我们就可以使用Swagger!所以我实现了一个Web API控制器,我希望在我的Sitecore实例中托管它并以某种方式记录它:
1
2
3
4
五
6
7
8
9
10
11
12
13
14
15
|
namespace Feature.WebApi.Controllers { using System.Web.Http; [RoutePrefix( "-/api/v1" )] public class MyServicesApiController : ApiController { [HttpGet] [Route( "hello-world" )] public IHttpActionResult HelloWorld() { return this .Ok( "Hello world" ); } } } |
好的,这是我的“hello world”API方法。现在我将使用nuget将Swagger安装到我的Feature.Swagger项目中:
1
|
install-package Swashbuckle |
默认的nuget包将在/App_Start/SwaggerConfig.cs中创建启动配置。默认情况下,它使用WebActivator扩展将其绑定到应用程序启动,以便在初始化Web应用程序时执行配置。
默认情况下,它不能与Sitecore平稳运行,但我们可以使用少量配置使其正常工作。Swagger UI的入口点是{your.domain.com} / swagger。我跑了,看下一张图:
为了解决它,我们需要修改/App_Start/SwaggerConfig.cs并取消注释下一行:
1
|
c.ResolveConflictingActions(apiDescriptions => apiDescriptions.First()); |
再次运行 - 我们看到下一个问题:
这次我们需要取消注释另一行配置:
1
|
c.UseFullTypeNameInSchemaIds(); |
好的,现在它已启动并运行,但是底部有一个annoing错误,表示存在架构验证错误。Swagger UI仍然有效,但我们真的不想看到任何错误消息吗?我们可以通过取消另外一行配置来绕过它:
1
|
c.DisableValidator(); |
Web API服务
现在它查找并运行,我甚至能够找到我的服务方法。但是,Sitecore有很多自己使用的Web API服务,很难找到我自己的服务。将Sitecore本机Web API控制器与我的分离是很好的。它支持API版本控制,从我的角度来看,这是我们如何分离它的方法之一。我们可以向SwaggerConfig添加一个方法,该方法将声明API的版本。
我将Sitecore服务称为版本“ sc ”,将我自己称为“ my_services ”:
1
2
3
4
五
6
|
private static bool ResolveVersionSupportByRouteConstraint(ApiDescription apiDesc, string targetApiVersion) { if (apiDesc.Route.RouteTemplate.StartsWith( "-/api/v1" ) && targetApiVersion == "my_services" ) return true ; if (apiDesc.Route.RouteTemplate.StartsWith( "sitecore" ) && targetApiVersion == "sc" ) return true ; return false ; } |
在配置中,我们需要注释/删除此行
1
|
c.SingleApiVersion( "v1" , "Feature.Swagger" ); |
并添加这个:
1
2
3
4
五
6
7
|
c.MultipleApiVersions( ResolveVersionSupportByRouteConstraint, vc => { vc.Version( "my_services" , "My services API (you can switch to Sitecore API /swagger/docs/sc)" ); vc.Version( "sc" , "Sitecore services (you can switch to My services API /swagger/docs/my_services)" ); }); |
现在我们为Sitecore API和My API提供了2个独立的视图。它们被Swagger UI视为API版本:
安装
或许,公开提供该文档并不是一个好主意,因为它会产生安全问题。因此,我们需要做的是在登录后隐藏Swagger UI,并使其仅供Sitecore管理员用户使用。我们可以重新使用Sitecore的默认登录页面。从我的角度来看,最好的方法是使用HTTP MessageHandlers。我们可以实现下一个消息处理器
1
2
3
4
五
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
三十
31
32
33
34
35
36
37
|
namespace Feature.Swagger { using System; using System.Net; using System.Net.Http; using System.Threading; using System.Threading.Tasks; using Sitecore; public class SwaggerSitecoreAuthMessageHandler : DelegatingHandler { protected override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { var isAuthenticated = Context.User?.IsAuthenticated ?? false ; var isAdministrator = Context.User?.IsAdministrator ?? false ; if ( this .IsSwaggerRequest(request) && (!isAuthenticated || !isAdministrator)) { var response = new HttpResponseMessage(HttpStatusCode.Redirect); var uri = request.RequestUri; var currentOrigin = uri.AbsoluteUri.Replace(uri.PathAndQuery, string .Empty); var logiPage = currentOrigin + @"/sitecore/login?returnurl=/swagger" ; response.Headers.Location = new Uri(logiPage); return Task.FromResult(response); } else { return base .SendAsync(request, cancellationToken); } } private bool IsSwaggerRequest(HttpRequestMessage request) { return request.RequestUri.PathAndQuery.ToLowerInvariant().StartsWith( "/swagger" ); } } } |
然后在SwaggerConfig类中添加一行,如下所示:
1
|
GlobalConfiguration.Configuration.MessageHandlers.Add( new SwaggerSitecoreAuthMessageHandler()); |
现在我们已成功将Swagger安装到Sitecore解决方案中。但是,正如我之前提到的,它使用WebActivator扩展,这更像是Web解决方案的反模式,我最好摆脱它,以保持螺旋原则。相反,我们可以使其更多Sitecore本地方式 - 在Sitecore初始化管道上运行配置。
所以首先我们要做的是删除这一行:
1
|
[assembly: PreApplicationStartMethod( typeof (SwaggerConfig), "Register" )] |
然后创建一个运行初始化的超简单初始化管道处理器:
1
2
3
4
五
6
7
8
9
10
11
12
|
namespace Feature.Swagger.Pipelines.Initialize { using Sitecore.Pipelines; public class InitializeSwagger { public void Process(PipelineArgs args) { SwaggerConfig.Register(); } } } |
当然我们需要将它添加到配置文件/App_Config/Include/Feature/Feature.Swagger.config中:
1
2
3
4
五
6
7
8
9
10
|
<?xml version="1.0" encoding="utf-8" ?> <configuration xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:set="http://www.sitecore.net/xmlconfig/set/">
<sitecore>
<pipelines>
<initialize>
<processor type="Feature.Swagger.Pipelines.Initialize.InitializeSwagger, Feature.Swagger" />
</initialize>
</pipelines>
</sitecore>
</configuration>
|
最后,我的完整SwaggerConfig.cs文件如下所示:
1
2
3
4
五
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
三十
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
namespace Feature.Swagger { using System.Web.Http; using System.Linq; using Swashbuckle.Application; using System.Web.Http.Description; public class SwaggerConfig { public static void Register() { var thisAssembly = typeof (SwaggerConfig).Assembly; GlobalConfiguration.Configuration.MessageHandlers.Add( new SwaggerSitecoreAuthMessageHandler()); GlobalConfiguration.Configuration .EnableSwagger(c => { c.MultipleApiVersions( ResolveVersionSupportByRouteConstraint, vc => { vc.Version( "my_services" , "My services API (you can switch to Sitecore API /swagger/docs/sc)" ); vc.Version( "sc" , "Sitecore services (you can switch to My services API /swagger/docs/my_services)" ); }); c.UseFullTypeNameInSchemaIds(); c.ResolveConflictingActions(apiDescriptions => apiDescriptions.First()); }) .EnableSwaggerUi(c => { c.DisableValidator(); }); } private static bool ResolveVersionSupportByRouteConstraint(ApiDescription apiDesc, string targetApiVersion) { if (apiDesc.Route.RouteTemplate.StartsWith( "-/api/v1" ) && targetApiVersion == "my_services" ) return true ; if (apiDesc.Route.RouteTemplate.StartsWith( "sitecore" ) && targetApiVersion == "sc" ) return true ; return false ; } } } |
就是这个。它与我们的Sitecore解决方案集成在一起。在他们的网站https://swagger.io上阅读有关所有Swagger功能的更多信息
我一直在使用Swagger和Sitecore 8.x以及Sitecore 9版本,一切正常!在这里查看我们的GitHub回购