2014-09-13 4 views
2

Можно ли определить маршруты, подобные Github, в ServiceStack? Я хотел бы определить REST API, как:Github-подобные маршруты в ServiceStack

home     /
account home   /{account} 
project detail   /{account}/{project} 
project issues index /{account}/{project}/issues 
project issues detail /{account}/{project}/issues/1 

Я пробовал:

[Route("/{Account}"] 
public class GetAccount : IReturn<AccountDto> { 
    public string Account { get; set; } 
} 

[Route("/{Account}/{Project}"] 
public class GetProject : IReturn<ProjectDto> { 
    public string Account { get; set; } 
    public string Project { get; set; } 
} 

// DTOs for issues, etc... 

Вышеприведенные DTOS бросить эту NotSupportedException при запуске:

RestPath '/{Account}' on Type 'GetAccount' is not Valid 

Это кажется довольно очевидным, что ServiceStack 4 не должен поддерживать этот прецедент (следовательно, NotSupportedException).

Мне просто интересно, есть ли способ определить пользовательскую маршрутизацию (или написать собственную маршрутизацию), чтобы этот сценарий работал.

ответ

3

Только специальный FallbackRoute can handle routes from the root path, как /{Account}, и поскольку он соответствует любой строке из корневого пути, может быть определен только один [FallbackRoute].

Маршруты, которые не содержат литерала, чтобы иметь возможность совпадать, например, /{Account}/{Project} также недействительны. Что вы можете сделать вместо этого есть служба Fallback, которая соответствует всем непарные маршруты и перенаправит запрос основан на том, сколько компонентов в информации пути, например:

[FallbackRoute("/{Path*}")] //matches all unmatched routes 
public class RootPathRoutes 
{ 
    public string Path { get; set; } 
} 

public class GetAccount : IReturn<Account> 
{ 
    public string Account { get; set; } 
} 

public class GetProject : IReturn<Project> 
{ 
    public string Account { get; set; } 
    public string Project { get; set; } 
} 

public class Account 
{ 
    public string Name { get; set; } 
} 

public class Project 
{ 
    public string Account { get; set; } 
    public string Name { get; set; } 
} 

Затем в резервной службе вы можете использовать компоненты в поле «Информация о пути» для вызова нужной услуги, например:

public class GitHubServices : Service 
{ 
    public object Any(RootPathRoutes request) 
    { 
     if (request.Path != null) 
     { 
      var parts = request.Path.Split('/'); 
      if (parts.Length == 1) 
       return Any(new GetAccount { Account = parts[0] }); 
      if (parts.Length == 2) 
       return Any(new GetProject { Account = parts[0], Project = parts[1] }); 
     } 

     return request; //passed to default page i.e. default.cshtml 
     //return HttpResult.Redirect("/metadata"); //e.g. of redirect response 
    } 

    public object Any(GetAccount request) 
    { 
     return new Account { Name = request.Account }; 
    } 

    public object Any(GetProject request) 
    { 
     return new Project { 
      Account = request.Account, 
      Name = request.Project, 
     }; 
    } 
} 
+1

Отлично. Для моей окончательной архитектуры я решил использовать более простые маршруты для всех моих DTO (учетные записи:/a/{Id}/{NameSlug}, проекты:/p/{Id}/{NameSlug}) и резервный маршрут для моего веб-клиента с схема URL выше (/ {account}/{project}). До сих пор хорошо работает! –