可以在 PostgreSQL 端验证 JSON 吗?

Posted

技术标签:

【中文标题】可以在 PostgreSQL 端验证 JSON 吗?【英文标题】:Is it okay to validate JSON at PostgreSQL side? 【发布时间】:2017-09-12 11:27:40 【问题描述】:

编写 API 我曾经在 Java(或 php,等等)端验证所有输入参数,但现在我们将 DB 移至 PostgreSQL,它为我们提供了出色的 JSON 功能,例如从表行构建 JSON 等等(我到目前为止,如果没有 PGSQL JSON 函数,我们就找不到任何东西)。所以我想如果我对 Postgres 进行所有参数验证(同时考虑到我可以直接从数据库返回 JSON)怎么办?

在 Java 中我是这样写的:

if (!params.has("signature")) 
//params comes from @RequestBody casted to JSONObject
    return errGenerator.genErrorResponse("e01"); //this also need database access to get error description

在 Postgres 上,我会这样(经过测试,按预期工作):

CREATE OR REPLACE FUNCTION test.testFunc(_object JSON)
  RETURNS TABLE(result JSON) AS
$$
BEGIN
  IF (_object -> 'signature') IS NULL --so needed param is empty
  THEN
    RETURN QUERY (SELECT row_to_json(errors)
                  FROM errors
                  WHERE errcode = 'e01');
  ELSE --everything is okay
    RETURN QUERY (SELECT row_to_json(other_table)
                  FROM other_table);
  END IF;
END;
$$
LANGUAGE 'plpgsql';

等等……

到目前为止,我看到的一个问题是,如果我们迁移到 MS SQL 或 Sybase,它将需要重写所有过程。但随着现在 NoSQL 越来越多,这似乎不太可能,如果我们转向 NoSQL DB,我们还必须重新编码所有 API

【问题讨论】:

您的问题终于解决了吗?你走哪条路? @joanolo 我得出了一些结论并回答了我自己的问题(你可以在下面阅读),所以我想说让大部分逻辑由 Java 负责,因为它允许你使所有东西都通用,因为例如ErrorDetail 对象,您可以在 DB 端自定义它,但错误不仅可能来自数据库验证阶段,这将导致您在 DB 和 Java 端准备相同的错误对象。如果你愿意,我可以告诉你更多我的想法:) 【参考方案1】:

你必须基本上考虑两个项目:

    您越靠近数据存储,它就越安全。如果您让数据库执行所有检查,那么无论您如何与它交互,无论是通过您的应用程序,还是通过您可能正在使用的某些第三方工具(即使只是为了维护),它们都将被执行。从这个意义上说,在数据库端进行检查可以提高安全性(如“数据一致性”)。在这方面,让数据库执行检查确实很有意义。

    您越靠近用户,您就能以最快的速度响应他/她的输入。如果您的 Web 应用程序需要快速响应时间,您可能希望在 客户端 端进行检查。

并考虑一个重要的:

    您可能还必须考虑您的团队知识:开发人员更熟悉什么。如果您对 Java 库的了解远胜于对数据库函数的了解……那么在 Java 端执行所有检查可能是有意义的。

您可以采用第三种方式:依次进行两种检查,首先是应用程序(客户端)端,然后是数据库(服务器)端。除非您有一些复杂的自动化,否则这需要额外的工作来确保执行的所有检查都是一致的。也就是说,不应该有任何数据在客户端被阻止,当数据库检查时会被允许通过。至少,最基本的检查是在第一阶段进行的,所有的检查(即使是多余的)都在数据库中进行。

如果您有时间在多个应用程序层中移动数据,我会选择安全的。但是,要根据具体情况做出选择。

【讨论】:

我同意你的观点,但我忘记了获取错误描述也需要访问数据库,所以我想我不会在 java 端进行检查获得速度优势......所以我应该深入思考根据您的建议。谢谢。【参考方案2】:

所以我找到了一些键...主要是我可以将我的错误消息缓存在我的应用程序中,如果输入参数没有传递它,这将允许避免发出数据库请求,并且只去数据库获取结果数据

【讨论】:

以上是关于可以在 PostgreSQL 端验证 JSON 吗?的主要内容,如果未能解决你的问题,请参考以下文章

PostgreSQL 中的 JSON 模式验证?

我可以完全在服务器端验证 Google Play 应用内订阅续订吗?

PostgreSQL 中 JSON 数据类型的大小限制

JSON 模式验证

可以对文件进行“干运行”验证吗?

Django/python 验证 JSON