ServiceStack路由和动词

Jez*_*tos 3 servicestack

我正在尝试在我们为业务创建的服务中建立编码模式(一些规则).我们遵循apigree为设计RESTful服务而提出的基本指导.

我们希望采用的规则之一是阻止我们不想支持的某些路由和动词组合.据推测,我们会发回一个HttpStatusCode.NotSupported用于这些非法组合,也许是一个人类可读的消息?

我们希望支持的法律组合是:

GET /resource - lists all resources
GET /resource/{id} - retrieves specific resource by ID
POST /resource - adds a new resource 
PUT /resource/{id} - updates specific resource by ID
DELETE /resource/{id} - deletes specific resource by ID
Run Code Online (Sandbox Code Playgroud)

我们明确不想支持一些非法组合.

POST /resource
PUT /resource
DELETE /resource
Run Code Online (Sandbox Code Playgroud)

我们为每个支持的路由都有验证器.但是我们在代码库中的任何地方都没有定义任何这些非法路由.

从测试中我们了解到,如果客户端发送一个GET /resource/{id}空白id(string.Empty)的请求,那么ServiceStack magic不会为该请求执行验证器(GET /resource/{id}),而是重定向到GET/resource.我们认为它DELETE /resource/{id}PUT /resource/{id}.但是这些'默认'行为都不可取,我们宁愿返回一个HttpStatusCode.NotSupported或一些标头指向客户端到API文档(或一些这样的指导).

您能否建议一些选项来在框架中明确处理这些情况?

干杯

myt*_*thz 5

如果您只想允许某些调用约定,那么您应该明确允许使用Route定义,例如:

[Route("/resource", "GET")]
public class GetAllResources {}

[Route("/resource/{Id}", "GET")]
public class GetResource 
{
    public int? Id { get; set; }
}

[Route("/resource", "POST")]
public class CreateResource { ... }

[Route("/resource/{Id}", "PUT")]
public class UpdateResource 
{
    public int Id { get; set; }
    ...
}

[Route("/resource/{Id}", "DELETE")]
public class DeleteResource 
{
    public int Id { get; set; }
    ...
}
Run Code Online (Sandbox Code Playgroud)

比你的服务只匹配你指定的动词:

public class ResourceServices : Service
{
    public object Get(GetResources request) { ... }
    public object Get(GetResource request) { ... }
    public object Post(CreateResource request) { ... }
    public object Put(UpdateResource request) { ... }
    public object Delete(DeleteResource request) { ... }
}
Run Code Online (Sandbox Code Playgroud)

什么不匹配将只是一个404 NotFound,因为没有匹配的路由将处理请求.

否则,您可以创建服务以专门捕获非法请求并根据需要对其进行处理,例如:

[Route("/resource", "DELETE PUT")]
public class IllegalActions {}

public class ResourceServices : Service
{
    public object Any(IllegalActions request) 
    {
        return new HttpError(HttpStatusCode.NotAcceptable, "ActionNotSupported");
    }
}
Run Code Online (Sandbox Code Playgroud)

错误处理维基做得很好,在显示所有可用的ServiceStack错误定制.能够将C#异常映射到Http状态代码在这里也可能有用:

SetConfig(new HostConfig { 
    MapExceptionToStatusCode = {
        { typeof(NotImplementedException), (int)HttpStatusCode.NotAcceptable },
        { typeof(NotSupportedException), (int)HttpStatusCode.NotAcceptable },
    }
});
Run Code Online (Sandbox Code Playgroud)