ServiceStack:在一个具有不同基本路径的AppHost上具有多个独立/不同的服务

时间:2019-02-08 03:37:58

标签: web-services servicestack

(编辑:我刚刚意识到自己suggested this in 2018

我已经读过one other post,我想问的是几乎相同的问题,但是我想我需要重新提问才能说明为什么这很重要:

我真的不喜欢必须在不同的端口上启动几个AppHost才能承载不同的服务。我可以在端口80上启动/greatService,在端口81上/superService等,但是我当然希望在一个端口上都使用它,所以:
mydomain.com/greatService
mydomain.com/superService

由于这些服务彼此独立,所以我不希望mydomain.com/metadata处的元数据页面描述greatServicesuperService。元数据页面应位于mydomain.com/<service>/metadata,并且仅描述该特定服务(子分支)。

编辑: 记住我在2018年的建议,我假设这是不可能的。那么,这意味着您只能为每个AppHost(因此每个端口)托管一项服务?因此,如果您有几种独立的服务(这是常见的情况),则建议您到底要做什么? =)

1 个答案:

答案 0 :(得分:0)

从根本上讲,ServiceStack主机只能有一个AppHost实例(每个AppDomain),可以通过HostContext.AppHost单例进行访问。

您不能在不同的路径上逻辑上托管/挂载“多个独立的服务组”,您可以通过Modularizing your Services到不同的程序集中获得相似的结果,并使[Route]明确包含前缀如果要托管每个服务,Routing docs描述了一些选项,可以通过实施自定义Auto Route Generation Strategy,通过overriding GetRouteAttributes()dynamically adding Route Attributes自定义定义的路由来使这些选项自动化。

我的偏好是明确包含您想要的路线

[Route("/greetService/hello")]
public class Greet { ... }

[Route("/superService/hello")]
public class Super { ... }

属性嵌入在元数据中,因此它们只能嵌入常量,因此您可以让所有Route使用相同的前缀,例如:

internal static class Routes
{
    public const string Prefix = "/greetService";
}

[Route(Routes.Prefix + "/hello")]
public class Greet { ... }

但是,尽管它们以不同的前缀分组,但仍分组在同一/metadata页下。在Add ServiceStack Reference功能中,如果它们被分组在不同的命名空间中,则可以Include All Types within a C# namespace使用:

/* Options:
IncludeTypes: MyApp.ServiceModel.Greet/*
...
*/

实现所需目标的最接近方法是利用Proxy Feature,它使您可以公开运行在不同名称或端口下的不同前缀下的ServiceStack实例,例如:

Plugins.Add(new ProxyFeature(
    matchingRequests: req => req.PathInfo.StartsWith("/techstacks"),
    resolveUrl:req => $"http://{resolve(req)}.techstacks.io"+req.RawUrl.Replace("/techstacks","/")))

Plugins.Add(new ProxyFeature(
    matchingRequests: req => req.PathInfo.StartsWith("/marketing"),
    resolveUrl:req => "http://marketing.domain.com" + req.RawUrl.Replace("/marketing", "/")))

Plugins.Add(new ProxyFeature(
    matchingRequests: req => req.PathInfo.StartsWith("/finance"),
    resolveUrl:req => "http://finance.domain.com" + req.RawUrl.Replace("/finance", "/")))