ServiceStack:是否可以在 URL 中指定基于上下文的路由? [英] ServiceStack: Is context based routing specified in the URL possible?

查看:20
本文介绍了ServiceStack:是否可以在 URL 中指定基于上下文的路由?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望保留过去使用 OData 服务但通过 ServiceStack 公开的服务层代码库中的大量功能,假设我实现了服务逻辑,我不想必须这样做为请求制作大量新的 DTO,当这基本上是我想要实现的目标时,除非框架强制"我声明一堆额外的类而没有功能增益......

I'm looking to retain a ton of functionality I used to have in my codebase from the service layer that I exposed previously using OData services but through ServiceStack, assuming I implement the service logic, I don't want to have to make a ton of new DTO's for requests when this is essentially what i'm trying to achieve unless the framework "forces" me to declare a bunch of extra classes for no functional gain ...

    [Route("~/{Type}")]
    public class GetRequest
    {
        public string Type {get; set; }
        public string Select { get; set; }
        public string Expand { get; set; }
        public string Filter { get; set; }
        public string GroupBy { get; set; }
        public string OrderBy { get; set; }
    }

    public ServiceBase<T> : Service
    {
       public virtual IEnumerable<T> Get(GetRequest<T> request) { ... }
    } 

    public FooService : ServiceBase<Foo> 
    { 
       public override IEnumerable<Foo> Get(GetRequest<Foo> request) { ... }
    } 

我能看到的唯一另一种实现方式是基本上必须创建一个 FooRequest DTO,它继承自这里的通用 DTO 并且不添加任何内容.

The only other way I can see to implement this is to basically have to create a FooRequest DTO that inherits from the generic one here and adds nothing.

虽然在某些情况下可能是这种情况,但对于我必须迁移的数百个端点中的大部分而言,这似乎很浪费,并且可能需要我不得不生成代码,服务堆栈声称不是需要".

Whilst this might be the case in some scenarios, for the bulk of the hundreds of endpoints I have to migrate this just seems wasteful and likely will require to me having to result to code generation, something Service Stack claims "isn't needed".

我的情况变得更糟,因为我有多个数据上下文"要考虑,例如......

My situation is made worse because I have "multiple data contexts" to consider for example ...

// base implementation for all services, derives from ServiceStack Service
public abstract class ServiceBase<T> : Service { ... }

// core service then one concrete implementation off that 
public class CoreService<T> : ServiceBase<T> { ... }
public CoreFooService : CoreService<Foo> { ... }

/// b2b service then one concrete implementation off of that 
public class B2BService<T> : ServiceBase<T> { ... }
public class BarB2BService : B2BService<Bar> { ... }

...使用基于 OData 的实现,我只需要添加每个新类即可为堆栈中的该类型数据添加一个自定义点.

... with my OData based implementation I only need to add each new class to add a point of customisation for that type of data in the stack.

对于 ServiceStack,对于服务类,这似乎仍然是可能的(我认为,但我不清楚路由是如何工作的)......我感到困惑的是理解请求 DTO,它们在所有 get 中基本相同请求但似乎无法根据 URL 中的某些类型信息进行路由.

With ServiceStack this still seems to be possible regarding service classes (i think, but i'm not clear on how the routing works) ... where I get confused is understanding the request DTOs which are basically the same in all get requests but seemingly not routeable based on some tpye information in the URL.

理想情况下,我想通过组合使用的 HTTP 动词和类似 [Route("~/{Context}/{Type}")] 的组合将标准请求 DTO 路由到服务方法(带有这是 DTO 上的属性用法).

Ideally I would like to route a standard Request DTO to a service method by a combination of the HTTP verb used and then something like [Route("~/{Context}/{Type}")] in the url (with that being the attribute usage on the DTO).

我觉得 ServiceStack 不是这样工作的,并且需要我为每个服务上的每个方法定义一个新的 DTO,我将不得不定义一堆新服务不存在,其中没有新的实现细节,只是为了满足框架需求.

I get the feeling though that ServiceStack doesn't work like this and is going to require me to define a new DTO for literally every method on every service and i'm going to have to define a bunch of new services that don't exist with no new implementation details in them just to satisfy the frameworks needs.

或者我错过了如何使用这里的框架来避免这项工作的一些技巧?

Or am i missing some trick in how to use the framework here to avoid this work?

推荐答案

你可以有多个 Service 基类,但你的 Request DTO 不能是通用的,它必须是一个具体的 Request DTO,但它可以继承基类,例如所有 AutoQuery RDBMS 服务都继承自 QueryDbQueryDb.

You can have multiple Service base classes but your Request DTO cannot be generic, it has to be a concrete Request DTO, but it can inherit base classes, e.g. All AutoQuery RDBMS Services inherit from QueryDb<T> or QueryDb.

你的路由应该以 / 开头(即不是 ~/),你可以有一个接受任何类型的参数:

Your Route should start with / (i.e. not ~/) and you could have a single Parameter that accepts any Type:


[Route("/data/{Type}")]
public class GetData
{
    public string Type {get; set; }
    public string Select { get; set; }
    public string Expand { get; set; }
    public string Filter { get; set; }
    public string GroupBy { get; set; }
    public string OrderBy { get; set; }
}

可以调用:

GET /data/Anything

但是您的服务应该具有相同的返回类型(即遵守其服务合同),因此通配符服务将没有用,除非您返回相同的非结构化数据响应,例如 DictionaryList

But your Service should have the same return Type (i.e. adhere to its Service Contract) so a wildcard Service is not going to be useful unless you return the same unstructured Data response like Dictionary<string,object>, List<object>, etc.

我觉得 ServiceStack 不是这样工作的,并且需要我为每个服务上的每个方法定义一个新的 DTO,我将不得不定义一堆新服务不存在,其中没有新的实现细节,只是为了满足框架需求.

I get the feeling though that ServiceStack doesn't work like this and is going to require me to define a new DTO for literally every method on every service and i'm going to have to define a bunch of new services that don't exist with no new implementation details in them just to satisfy the frameworks needs.

是的 ServiceStack 要求每个服务由其请求 DTO 定义,请求 DTO 是描述该服务合同的主权限.这不仅仅是安抚框架的要求,请求 DTO 是调用服务,这是通用服务客户端唯一需要的东西发送来调用一个服务,如果它不存在就不能发送,如果没有类型,它也不能有类型化的API(没有代码生成).

Yes ServiceStack Requires every Service is defined by its Request DTO which is the master authority describing that Services contract. This is not just a requirement to appease the Framework, the Request DTO is the message that invokes a Service, which is the only thing generic Service Clients need to send to invoke a Service, which it can't send if it doesn't exist, nor can it have a Typed API (without code-gen) if there are no types.

这篇关于ServiceStack:是否可以在 URL 中指定基于上下文的路由?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆