如何从没有副作用的验证中提供有意义的错误反馈?

时间:2015-05-14 16:14:08

标签: java validation rest

我正在尝试找出一种管理REST端点验证的简洁方法,这样我就可以在出现错误(HTTP状态代码和一些错误消息)的同时为用户提供有意义的反馈,同时避免验证方法中的副作用也在进行工作。

例如,我需要解析一个json对象,首先我需要验证它是否解析并获取代表它的对象。如果我在解析过程中遇到异常,那么我想告诉用户,但是如果它正确解析,我还想从验证方法中取回对象。

这里有两个问题,验证并将json字符串转换为POJO。如果我将它们放在相同的方法中,那么如果解析失败而没有副作用,如何返回错误字符串?

超级伪代码显示一种可能性,但有副作用:

public Pet parsePet(HTTPResponse httpResponse, String petStr) {
    Pet pet = null;
    try {
        Parser parser = new Parser();
        pet = parser.parse(petStr, Pet.class);
    } catch(Exception e) {
        httpResponse.setStatus(400);
    }
    return pet;
}

显然在这种情况下,我可以使用空响应来确定它没有解析并避免副作用,但是在一个更复杂的例子中,不同的错误会产生不同的错误状态'我怎样才能避免副作用?

对于这类事情,是否有一些标准的最佳实践或架构概念?

我能想到的“最干净”选项是抛出一些新的异常,例如ValidationException(int statusCode),当业务规则被破坏时可能抛出。但随后整个“特殊事物的例外”开始发挥作用。鉴于我最终向用户返回了一个错误,但似乎异常在某种程度上是可以接受的。

3 个答案:

答案 0 :(得分:0)

  

如果我将它们放在同一个方法中,那么如果解析失败而没有副作用,如何返回错误字符串?

发生错误时抛出异常。更高的东西会解释它并将其转换为http错误响应。

你可以做的其他来自Haskell世界的东西就是让这个方法返回Either<Pet, Error>。将填写这两个中的一个(PetError)。调用者需要确定哪一个。我只是在这里给你一个选项,这不是我在惯用的Java代码中看到的。

  

我能想到的“最干净”选项是抛出一些新的异常,例如ValidationException(int statusCode)

我认为抛出一个PetParsingException是一个smidgen清洁器,更高的东西解释异常并判定它是400.你的验证不 知道它是宁静的api的一部分。

答案 1 :(得分:0)

创建一个用于存储错误的新界面:

interface ValidationErrors 
{
    public void addError(String message); 
    public List<String> getErrors(); 
}

更改parsePet方法以接受ValidationErrors的对象而不是HTTPResponse。

public Pet parsePet(String petStr, ValidationErrors errors) {
    try {
        Parser parser = new Parser();
        pet = parser.parse(petStr, Pet.class);
    } catch(Exception e) {
        errors.addError("Parsing pet failed: " + e.getMessage());
        return null; 
    }

    return pet;
}

然后,您可以实现一种方法,将ValidationErrors对象转换为适当的HTTPResponse配置。

ValidationErrors可以随着您的需求而增长 - i。即也许你想在那里存储异常,提供遇到的错误的摘要,或使用自动记录。

PS:Spring验证器使用类似的方法。

答案 2 :(得分:0)

将异常抛出业务方法(可能包含在一些ValidationException中并附带其他详细信息),并让它在方法调用堆栈的更高级别处理。

“更高级别”实际上是一些Web框架错误处理实用程序。在那里,您可以决定如何处理错误 - 返回具有适当HTTP状态的消息,重试该操作或其他内容。

这将使代码更清晰(为此目的已经发明了异常),它实际上将帮助您避免不良副作用(通过回滚事务和类似事件)。