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 列表的单个批处理服务来获得更多实用性存在。