【问题标题】:Net Core REST API - Returning JSON with and without a modelNet Core REST API - 返回带有和不带有模型的 JSON
【发布时间】:2021-04-13 07:14:22
【问题描述】:

关于 HttpGet 操作...

数据库正在返回一个完整的 JSON 字符串,在返回给用户之前不需要翻译。

目前,我正在将此 JSON 反序列化为 C# 模型/类,然后返回该模型。

仅返回从数据库返回的 JSON 字符串(不再使用 C# 模型)有哪些权衡?

我之所以这么问,是因为就模型提供的好处而言,这似乎是一种反模式。

请注意,我知道不必将 JSON 从 DB 反序列化到模型中,然后将模型序列化回 JSON 字符串以响应客户端,从而节省了时间。然而,

模型示例:

        var response = await GetDataByParams(functionName, npgSqlParams);

        List<EmployeeInfo> model = JsonConvert.DeserializeObject<List<EmployeeInfo>>(response);

        return model;

对比:

        var response = await GetDataByParams(functionName, npgSqlParams);

        return response;

注意:我们使用的是 postgres 和 Npgsql。不使用实体框架。

注意:我们使用的是 Swagger,所以我知道我们会丢失 API 文档中的模型定义。

问题:这对 API 的模拟测试有何影响?

问题:如果 JSON 更改并违反与客户端的合同怎么办? 我的想法是使用模型可以保证合同。如果从数据库返回的 JSON 违反了模型,那么服务器上就会发生异常。不使用模型会将异常推送回客户端。

【问题讨论】:

    标签: c# json asp.net-core asp.net-web-api .net-core


    【解决方案1】:

    作为一般惯例,指示不要将域模型/域响应直接返回给客户端。为此使用 DTO(如 EmployeeInfo)是正确的方法。

    通过使用 DTO,您可以更好地控制输出数据,包括序列化选项、隐藏您不想向客户端公开的属性。

    此外,如果您的域发生变化,您的 DTO 将保持不变,客户端不会受到影响。

    【讨论】:

    • 在这种情况下,不需要操作数据。没有隐藏数据。
    • 澄清一下,问题实际上是,不使用模型/DTO 而是只返回 postgres 函数提供的直接 JSON 的权衡是什么。
    • 如果不使用 DTO,服务消费者(客户端)更容易受到域更改的影响。我认为跳过反序列化过程不会节省大量时间/资源。
    【解决方案2】:

    直接从数据库中返回字符串,避免了

    的开销
    • 反序列化为 DTO 和
    • 控制器返回 DTO 后重新序列化为 JSON,但是
    • 测试会更加脆弱,因为它们将依赖字符串匹配等,而且测试断言的意图不会像使用 DTo 属性的断言那样容易表达。

    首先将数据库序列化为 DTO

    • 增加了开销,但是
    • 允许您首先与 DTO 进行任何操作或其他类型安全的交互,并且
    • 便于测试

    还有一种使用JObject.Parse()(如果是Newtonsoft)或JsobDocument.Parse()(如果是System.Text.Json)标记JSON的混合方法

    • 标记结果,让您可以
    • 在没有 DTO 的情况下操作结构,并且
    • 可以通过访问解析的结构进行合理的测试

    您必须对其进行衡量,但第一种方法可能会为您提供最高的性能,但灵活性最低(后者,这似乎是您愿意为您的情况接受的权衡)。

    第二种方法可能是“在野外”最常见的情况,并且在大多数情况下最有意义。您提出的关于 DTO 如何通过立即显示“损坏的”合同来呈现安全性的观点是一个很好的观点。及早了解这些类型的错误可以降低 API 的维护成本,并减少客户端得到错误结果的机会。

    【讨论】:

    • 谢谢。我知道不反序列化/序列化可能会带来一些性能优势。这些都是小物件。当我进一步思考时,我想知道它如何影响 API 的模拟测试。使用 POCO 类很容易模拟测试。如果我必须创建 JSON 测试字符串来模拟测试 API,如果有人更改它,我们将面临测试 json 字符串与函数的子响应不匹配的风险......
    • 可测试性绝对是一个方面。我会把它添加到...
    • 谢谢。感谢您抽出时间与我一起思考这个问题。
    猜你喜欢
    • 1970-01-01
    • 2019-01-06
    • 2020-03-17
    • 2021-02-05
    • 1970-01-01
    • 2019-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多