【问题标题】:ServiceStack - Head Requests in Service GatewayServiceStack - 服务网关中的头请求
【发布时间】:2019-11-15 12:21:47
【问题描述】:

我有一个验证器,它必须检查另一个实体是否存在。我希望能够使用 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


    【解决方案1】:

    您无法在 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 并返回一个字典或存在的 ID 列表。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-10-28
      • 1970-01-01
      • 2020-01-01
      • 1970-01-01
      • 2012-08-19
      • 2019-06-07
      • 1970-01-01
      • 2018-04-16
      相关资源
      最近更新 更多