Disham Parikh
Disham Parikh

Reputation: 21

ServiceStack.Api.Swagger SwaggerResourcesService excluding Routes begining with Route Parameter

I am using Servicestack version 4.0.52.0 and ServiceStack.Api.Swagger 4.0.0.0

I have defined all routes with variable route parameter in serviceStack application host derived class(AppHostBase):Configure method

public class AppHost : AppHostBase
{
    public override void Configure(Funq.Container container)
    {
        //Infrastructure code goes here
        ....

        //Add routes
        Routes.Add<TestRequestDTO>("/{MyApplicationKey}/TestOperation/", "GET")
    }
}

Although these routes are visible in ServiceStack metadata page, swagger UI does not show routes begining with MyApplicationKey; Digging deeper into codebase of we found the issue in ServiceStack.Api.Swagger.SwaggerResourcesService.Get method:

 [AddHeader(DefaultContentType = MimeTypes.Json)]
    [DefaultRequest(typeof(SwaggerResources))]
    [Restrict(VisibilityTo = RequestAttributes.None)]
    public class SwaggerResourcesService : Service
    {
        private readonly Regex resourcePathCleanerRegex = new Regex(@"/[^\/\{]*", RegexOptions.Compiled);
        internal static Regex resourceFilterRegex;

        internal static Action<SwaggerResourcesResponse> ResourcesResponseFilter { get; set; }

        internal const string RESOURCE_PATH = "/resource";

        public object Get(SwaggerResources request)
        {
            var basePath = base.Request.GetBaseUrl();

            var result = new SwaggerResourcesResponse
            {
                BasePath = basePath,
                Apis = new List<SwaggerResourceRef>(),
                ApiVersion = HostContext.Config.ApiVersion,
                Info = new SwaggerInfo
                {
                    Title = HostContext.ServiceName,
                }
            };
            var operations = HostContext.Metadata;
            var allTypes = operations.GetAllOperationTypes();
            var allOperationNames = operations.GetAllOperationNames();
            foreach (var operationName in allOperationNames)
            {
                if (resourceFilterRegex != null && !resourceFilterRegex.IsMatch(operationName)) continue;
                var name = operationName;
                var operationType = allTypes.FirstOrDefault(x => x.Name == name);
                if (operationType == null) continue;
                if (operationType == typeof(SwaggerResources) || operationType == typeof(SwaggerResource))
                    continue;
                if (!operations.IsVisible(Request, Format.Json, operationName)) continue;

                CreateRestPaths(result.Apis, operationType, operationName);
            }

            result.Apis = result.Apis.OrderBy(a => a.Path).ToList();

            if (ResourcesResponseFilter != null)
                ResourcesResponseFilter(result);

            return new HttpResult(result) {
                ResultScope = () => JsConfig.With(includeNullValues:false)
            };
        }

        protected void CreateRestPaths(List<SwaggerResourceRef> apis, Type operationType, string operationName)
        {
            var map = HostContext.ServiceController.RestPathMap;
            var feature = HostContext.GetPlugin<SwaggerFeature>();

            var paths = new List<string>();

            foreach (var key in map.Keys)
            {
                paths.AddRange(map[key].Where(x => x.RequestType == operationType).Select(t => **resourcePathCleanerRegex.Match**(t.Path).Value));
            }
 ......
}

Any hints on how we can fix the issue? Is there any way to tell value of MyApplicationKey to Swagger API when it is doing resource listing?

Upvotes: 2

Views: 232

Answers (1)

mythz
mythz

Reputation: 143399

There is an opportunity to modify the Swagger Response by specifying a custom ResourcesResponseFilter when you register the SwaggerFeature plugin, e.g:

Plugins.Add(new SwaggerFeature {
    ResourceFilterPattern = @"/[^\/\{]*",
    ResourcesResponseFilter = response => ...
});

Which will let you modify the Swagger Response that the Swagger UI receives.

Upvotes: 2

Related Questions