需要我的服务器 return 包含数据错误的响应。需要客户查看请求中的数据有什么问题

Need my server to return a response that includes a data error. Need client to see what was wrong with data in request

很快就会明白,我以前从未认真编写过网络服务器

这是当前的场景:

  1. 客户端向网络服务器发出请求,要求保存一些数据
  2. 服务器查看负载,并进行 2 次检查
    一种。此客户端是否被禁止保存数据?
    b.此数据的有效负载是否通过了语言过滤器?
  3. 服务器响应成功,或 2 个错误之一

我的端点是用 TypeScript 中的 Express 编写的

class ChatRequest {
  public uid: string;
  public message: string;
}


export const register = (app: express.Application, deps: dependencies.IDependencies) => {
  app.post("/sendChat", (req: express.Request, res: express.Response) => {
    transformAndValidate(ChatRequest, req.body)
      .then((sendGlobalChatRequest: SendGlobalChatRequest) => {
        const payload = {
          message: sendGlobalChatRequest.message,
          uid: sendGlobalChatRequest.uid
        };

        //Check if uid is banned here

        //Check if payload passes language filter here

        //Save Payload here

        res.sendStatus(200);
      }, (err) => {
        deps.logger.error(err);
        res.sendStatus(503);
      });
  });

我一直在参考这篇文章: https://hackernoon.com/the-request-sent-bad-data-whats-the-response-94088bd290a

但我认为我的结论是他们讨论的内容略有不同。

所以根据我的理解,我可以编写 HTTP 代码... 所以如果 uid 被禁止,我可以 res.sendStatus(499);,如果有效载荷没有通过语言过滤器,我可能 res.sendStatus(498);

然后我的客户端可以只读Int statusCode 并快速确定失败。

但即使我认为我可以做到,而且它会起作用,但它似乎不对?

我应该改用标准的 HTTP 响应代码吗? https://developer.mozilla.org/en-US/docs/Web/HTTP/Status

然后在响应正文中添加 String 或我的客户可以解析以确定错误的内容?

字符串解析似乎更难维护,但从技术上讲似乎更 "legal" 如果这有意义?

让客户端确定服务器端错误类型的最佳方法是什么?

我决定 return 400 JSON 将错误映射到 bools

    if (isProfane(message)) {
      res.status(400).json({messageContentBlocked: true});
    }

这样客户端可以一次收到多个请求错误,更明确

如果有人在谷歌上搜索,我正在使用 RxSwift/RxCocoa

以下是我在客户端处理错误的方式:

extension Error {
    var chatMessageBlockedURLError: Bool {
        guard let rxCocoaURLError = self as? RxCocoaURLError else {return false}
        switch rxCocoaURLError {
        case let .httpRequestFailed(response, data):
            guard response.statusCode == 400, let data = data else {return false}
            let decoder = JSONDecoder()
            decoder.dateDecodingStrategy = .millisecondsSince1970
            guard let errors = try? decoder.decode([String:Bool].self, from: data) else {return false}
            return errors["messageContentBlocked"] == true
        default:
            return false
        }
    }
}