【问题标题】:Use Java exceptions internally for REST API user errors?在内部使用 Java 异常处理 REST API 用户错误?
【发布时间】:2011-02-12 04:41:03
【问题描述】:

我们有一个运行良好的 REST API。我们正在重构并决定如何在内部处理 API 用户的错误。

例如,用户需要指定“电影”url 参数,该参数应该取“1984”、“Crash”或“Avatar”的值。首先,我们检查它是否具有有效值。

如果电影参数无效,最好的方法是什么?

  • 从内部方法之一返回 null 并在主要 API 调用方法中检查 null
  • 从内部方法抛出异常并在主 API 方法中捕获异常

我认为使用异常会使我们的代码更具可读性和优雅。然而,我们很不情愿,因为我们可能会因为用户 API 输入错误而引发许多异常,我们的代码可能是完美的。这似乎不是对异常的正确使用。如果异常会导致严重的性能损失,这对于需要收集堆栈跟踪等是有意义的,那么当我们需要做的只是告诉用户参数错误时,我们就会不必要地消耗资源。

这些是 REST API 方法,因此我们不会向 API 用户传播异常,即使可能我们也不想这样做。

那么这里的最佳做法是什么?使用丑陋的 null 还是使用 java 的异常机制?

【问题讨论】:

  • 当用户传入一个“无效”的电影参数时,这是否代表用户犯了一个错误,还是只是搜索未命中?

标签: api null exception


【解决方案1】:

都没有。

关键是传递一个错误的参数并不是一个例外情况。异常情况下会抛出异常。 (这就是不在这里使用它们的原因,而不是性能。)

您应该使用 Spring 的 DataValidation API 之类的东西来绑定传入的参数。

REST API 的客户端不应接收 null 或异常。他们应该会收到一条错误消息,让他们了解正在发生的事情,而不会暴露这些细节。 “抱歉,我们找不到那部电影”或 null?先放手,放下手。

【讨论】:

  • 没错。 RESTful API 应该像任何其他应用程序一样验证用户输入。如果输入错误,请告诉用户原因。如果错误的输入使其通过了您的过滤器/验证,那么这是引发异常、记录异常并通知开发团队以便他们修复验证(或任何错误)的适当时间。
【解决方案2】:

我假设您在这里进行输入验证,在这种情况下,您的数据库将查询一个安全的字符串,但它不会找到该记录,因为它不存在于您的数据库中,好吗?

如果您使用任何 MVC 框架,模型应该已经抛出 RecordNotFound 异常,不是吗?

如果您总是希望找到一个值,那么如果它丢失则抛出异常。异常意味着存在问题。

如果值可能缺失或存在,并且两者都对应用程序逻辑有效,则返回 null。

更重要的是:你在代码的其他地方做什么?一致性很重要。

【讨论】:

    【解决方案3】:

    如果收到无效请求(例如验证错误),您应该显示 400 状态代码(错误请求)。

    在内部,我还将创建一个映射到 HTTP Rest 域的异常层次结构(请参阅错误案例的状态代码)。

    示例(简化和未经检查的异常):

    class RESTBaseException extends RuntimeException{ int statusCode; public RESTBaseException(int statusCode){ this.statusCode=statusCode; } //if no statusCode passed we fallback to very broad 500 server error. public RESTBaseException(){ this.statusCode=500; } } class RESTValidationException extends RESTBaseException{ RESTValidationException(){ super(404); } }

    您还可以通过将错误消息传递给构造函数来扩展上述示例,以使客户更加满意。

    稍后您应该使用 servlet 处理程序链中的专用异常处理程序来捕获这些异常(将状态代码映射到 servlet 响应)。例如在 spring mvc 中有很好的异常处理解决方案。

    通常我不喜欢创建深度自定义异常层次结构,但我认为对于 REST api 层来说它们是可以的(因为稍后会传播状态代码)。

    【讨论】:

      猜你喜欢
      • 2020-02-19
      • 1970-01-01
      • 2015-02-14
      • 2012-12-08
      • 2023-02-26
      • 1970-01-01
      • 1970-01-01
      • 2010-09-10
      • 1970-01-01
      相关资源
      最近更新 更多