ServiceStack - 服务网关中的头部请求
ServiceStack - Head Requests in Service Gateway
我有一个必须检查另一个实体是否存在的验证器。我希望能够使用 HEAD 方法调用 ServiceGateway 来检查 404/200 的状态。 .
现在,我正在做一个卑鄙的把戏。我发出了一个常规的 GET 请求,周围是 try/catch。但如此多的 404 严重污染了我的日志。另外,有时,我必须检查某个实体是否不存在。所以我的日志显示 404s 错误,但这是预期的。
我可以实现另一个 DTO 来检查它,但我更愿意使用现有的 HTTP 约定
我尝试使用 ServiceGateway / 自定义 BasicRequest
但是我有两个问题
我无法访问 ServiceGateway IResponse (Gateway.Send().Response.StatusCode)。
我无法将动词设置为 HEAD(InProcess 仅支持 GET,POST,DELETE,PUT,OPTIONS,PATCH)
此外,通常没有 IHead 接口/HEAD 支持
我的问题是:如何在内部使用服务网关发出 HEAD 请求,以检查是否存在(或缺少)其他实体? - 通过 InProcess、Grpc、Json、...
此外,这对于访问已经内置的版本控制(Etags,...)很有用
[Route("/api/other-entity/{Id}", "GET,HEAD")]
public class GetOtherEntity : IReturn<OtherEntityDto>, IGet
{
public Guid Id {get; set;}
}
public class OtherEntityService : Service {
public async Task<object> Get(GetOtherEntity request){
return (await _repository.Get(request.Id)).ToDto();
}
// This doesn't get called
public async Task Head(GetOtherEntity request){
var exists = await _repository.Exists(request.Id);
Response.StatusCode = exists ? (int)HttpStatusCode.OK : (int)HttpStatusCode.NotFound;
}
// This either
public async Task Any(GetOtherEntity request){
var exists = await _repository.Exists(request.Id);
Response.StatusCode = exists ? (int)HttpStatusCode.OK : (int)HttpStatusCode.NotFound;
}
}
public class CreateMyEntityValidator: AbstractValidator<CreateMyEntity>{
public CreateMyEntityValidator(){
// This rule ensures that the OtherId references an existing OtherEntity
RuleFor(e => e.OtherId).MustAsync(async (entity, id, cancellationToken) => {
var query = new GetOtherEntity(){ Id = id };
var request = new BasicRequest(query , RequestAttributes.HttpHead);
// This doesn't call the OtherService.Head nor the OtherService.Any
// Actually my logs show that this registers a a POST request ?
var response = await HostContext.AppHost.GetServiceGateway(Request).SendAsync(request);
// And how could I get the response.StatusCode from here ?
return response.StatusCode == (int)HttpStatusCode.OK;
})
}
}
您不能在 ServiceStack 服务中实现 HEAD 请求。
你可以在ServiceStack之前通过在Pre Request Filters中拦截和短路它们来处理它们,例如:
RawHttpHandlers.Add(httpReq =>
httpReq.HttpMethod == HttpMethods.Head
? new CustomActionHandler(
(httpReq, httpRes) =>
{
// handle request and return desired response
httpRes.EndRequest(); //short-circuit request
});
: null);
但是很少有 HTTP 客户端会原生支持 HEAD 请求,通常您只是尝试获取资源,如果目标资源不存在,则会抛出 404 异常。
如果您需要经常检查资源是否存在而不返回它,您将通过实现接受一批 ID 或 URN 和 returns 字典或 ID 列表的单个批处理服务来获得更多实用性存在。
我有一个必须检查另一个实体是否存在的验证器。我希望能够使用 HEAD 方法调用 ServiceGateway 来检查 404/200 的状态。 .
现在,我正在做一个卑鄙的把戏。我发出了一个常规的 GET 请求,周围是 try/catch。但如此多的 404 严重污染了我的日志。另外,有时,我必须检查某个实体是否不存在。所以我的日志显示 404s 错误,但这是预期的。
我可以实现另一个 DTO 来检查它,但我更愿意使用现有的 HTTP 约定
我尝试使用 ServiceGateway / 自定义 BasicRequest
但是我有两个问题
我无法访问 ServiceGateway IResponse (Gateway.Send().Response.StatusCode)。
我无法将动词设置为 HEAD(InProcess 仅支持 GET,POST,DELETE,PUT,OPTIONS,PATCH)
此外,通常没有 IHead 接口/HEAD 支持
我的问题是:如何在内部使用服务网关发出 HEAD 请求,以检查是否存在(或缺少)其他实体? - 通过 InProcess、Grpc、Json、...
此外,这对于访问已经内置的版本控制(Etags,...)很有用
[Route("/api/other-entity/{Id}", "GET,HEAD")]
public class GetOtherEntity : IReturn<OtherEntityDto>, IGet
{
public Guid Id {get; set;}
}
public class OtherEntityService : Service {
public async Task<object> Get(GetOtherEntity request){
return (await _repository.Get(request.Id)).ToDto();
}
// This doesn't get called
public async Task Head(GetOtherEntity request){
var exists = await _repository.Exists(request.Id);
Response.StatusCode = exists ? (int)HttpStatusCode.OK : (int)HttpStatusCode.NotFound;
}
// This either
public async Task Any(GetOtherEntity request){
var exists = await _repository.Exists(request.Id);
Response.StatusCode = exists ? (int)HttpStatusCode.OK : (int)HttpStatusCode.NotFound;
}
}
public class CreateMyEntityValidator: AbstractValidator<CreateMyEntity>{
public CreateMyEntityValidator(){
// This rule ensures that the OtherId references an existing OtherEntity
RuleFor(e => e.OtherId).MustAsync(async (entity, id, cancellationToken) => {
var query = new GetOtherEntity(){ Id = id };
var request = new BasicRequest(query , RequestAttributes.HttpHead);
// This doesn't call the OtherService.Head nor the OtherService.Any
// Actually my logs show that this registers a a POST request ?
var response = await HostContext.AppHost.GetServiceGateway(Request).SendAsync(request);
// And how could I get the response.StatusCode from here ?
return response.StatusCode == (int)HttpStatusCode.OK;
})
}
}
您不能在 ServiceStack 服务中实现 HEAD 请求。
你可以在ServiceStack之前通过在Pre Request Filters中拦截和短路它们来处理它们,例如:
RawHttpHandlers.Add(httpReq =>
httpReq.HttpMethod == HttpMethods.Head
? new CustomActionHandler(
(httpReq, httpRes) =>
{
// handle request and return desired response
httpRes.EndRequest(); //short-circuit request
});
: null);
但是很少有 HTTP 客户端会原生支持 HEAD 请求,通常您只是尝试获取资源,如果目标资源不存在,则会抛出 404 异常。
如果您需要经常检查资源是否存在而不返回它,您将通过实现接受一批 ID 或 URN 和 returns 字典或 ID 列表的单个批处理服务来获得更多实用性存在。