在内部使用 Java 异常来处理 REST API 用户错误?

发布于 2024-08-30 01:59:01 字数 512 浏览 1 评论 0原文

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

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

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

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

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

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

那么这里的最佳实践是什么?使用丑陋的空值还是使用java的异常机制?

We have a REST API that works great. We're refactoring and deciding how to internally handle errors by the users of our API.

For example the user needs to specify the "movie" url parameter which should take the value of "1984", "Crash", or "Avatar". First we check to see if it has a valid value.

What would be the best approach if the movie parameter is invalid?

  • return null from one of the internal methods and check for the null in the main API call method
  • throw an exception from the internal method and catch exceptions in the main API method

I think it would make our code more readable and elegant to use exceptions. However, we're reluctant because we'd be potentially throwing many exceptions because of user API input errors, our code could be perfect. This doesn't seem to be the proper use of exceptions. If there are heavy performance penalties with exceptions, which would make sense with stack traces needing to be collected, etc., then we're unnecessarily spending resources when all we need to do is tell the user the parameter is wrong.

These are REST API methods, so we're not propogating the exceptions to the users of the API, nor would we want to even if possible.

So what's the best practice here? Use ugly nulls or use java's exception mechanism?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

心如狂蝶 2024-09-06 01:59:01

两者都不。

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

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

API 的客户端不应该接收 null 或异常。他们应该收到一条错误消息,让他们了解正在发生的情况,而无需暴露这些详细信息。 “抱歉,我们找不到那部电影”或 null?毫无疑问,选择第一个。

Neither.

The key is that passing a bad parameter isn't that exceptional a condition. Exceptions are thrown for exceptional circumstances. (That's the reason to not use them here, not the performance.)

You should be using something like Spring's DataValidation API for binding parameters that are passed in.

A client of a REST API should not be receiving null or exceptions. They should get an error message that gives them an idea of what's going on without exposing those details. "Sorry, we couldn't find that movie" or null? Go with the first, hands down.

薯片软お妹 2024-09-06 01:59:01

如果收到无效请求(例如验证错误),您应该显示 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 层来说它们是可以的(因为状态代码稍后传播)。

If a invalid request came in (e.g. validation error) you should show 400 status code (bad request).

Internally I would also create an exception hierachy which maps to the HTTP Rest domain (see status codes for error cases).

Examples (simplified and being unchecked exceptions):


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);
   }
}

you can extend above examples by also passing error messages to constructor to make client even more happy.

Later on you should catch these exceptions with a dedicated exception handler in your servlet handler chain (mapping status code to servlet response). For instance in spring mvc there are nice exception-handling solutions for that.

Usually I don't like to create a deep custom exception hierachies but I think for REST api layers they are OK (because the status codes are propagated later).

鲜肉鲜肉永远不皱 2024-09-06 01:59:01

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

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

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

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

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

I will assume that you are doing input validation here and in this case, your database will do a query for a safe string and it won't find the record since it don't exist in your database, ok?

If you are using any MVC framework the Model should throw already a RecordNotFound exception no?

If you are always expecting to find a value then throw the exception if it is missing. The exception would mean that there was a problem.

If the value can be missing or present and both are valid for the application logic then return a null.

More important: What do you do in other places of the code? Consistency is important.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文