数据库的数据应在何处转换



数据库的数据应该在哪里转换?我认为这叫做数据规范化/净化。

在我的数据库中,我有用户创建的商店——就像Etsy一样。假设用户在他们的商店中输入商品的价格为"0";1000.00";。但我的数据库将价格存储为整数/便士-";100000";。哪里应该";1000.00〃;被转换为";100000";?

这是我想到的两种方式。

  1. 在前端:输入数据从";1000.00〃;至";100000";在HTTP请求之前的前端。在这种情况下,后端将验证价格是否为整数。

  2. 在后端:";1000.00〃;按原样发送到后端,然后后端验证它是价格格式,然后后端将价格转换为整数";100000";然后存储在数据库中。

这似乎要么可行,但有一种方法比另一种更好,或者有标准的方法吗?我认为第二种方法是减少代码重复的最佳方法,因为可能有多个前端(移动、web等)和一个后端。但第一种方式似乎也更干净——只需发送api所需的内容。

如果这有什么不同的话,我正在使用MERN应用程序,但我认为这将是语言无关的。

我会将两者混合使用(这是一种最佳实践,AFAIK)。

前端无论如何都必须进行某种验证,因为你不想等待后端得到验证响应。我也会在这里添加实际的转换。

我想验证代码将适用于每个前端,因为每个前端都有不同的框架/语言,所以我不一定在这里看到代码重复(逻辑是的,但不是实际的代码)。最后,您可以创建一个通用的验证库。

后端应该再次验证前端发送的转换值,就像进行双重检查一样,然后将其存储在数据库中。您永远不知道后端将来是否会与其他组件集成,输入清理始终是最佳实践。

短版本

这两种方法都可行,我认为没有标准的方法。我更喜欢前端的格式。


长版本

在这种情况下,我所做的是查看我预期的业务需求,并列出利弊。以下是对此的一些想法。

  1. 如果您决定在前端进行每一次价格转换(格式化、规范化、净化),您的后端将保持较小,并且您将拥有更少的端点或具有更少选项的端点。根据前端,您可以选择最适合您的最终用户。交付的代码量将保持较小,因为应用程序可以被缓存并进行所有格式化
  2. 如果您在后端实现了所有内容,那么您就可以完全控制向用户提供的格式。特别是在处理许多不同的语言时,直接从服务器获取正确的显示值可能会有所帮助

此外,了解知名供应商的一些不同API以及这些API如何处理价格可能会有所帮助。

PaypalAPI使用金额对象将价格作为小数与货币代码一起传输。

"amount": {
"value": "9.87",
"currency": "USD"
}

如何在前端处理它取决于你。以下是一个链接,其中包含来自文档的示例请求:

  • https://developer.paypal.com/docs/api/payments.payouts-batch/v1#payouts_post

Stripe使用了一个略有不同的模型。

{
unit_amount: 1600,
currency: 'usd',
}

它有以货币为基本单位的整数值作为金额,并有一个描述价格的货币代码。以下是两个更清楚的例子:

  • https://stripe.com/docs/api/prices/create?lang=node
  • https://stripe.com/docs/checkout/integration-builder

在这两种情况下,都必须在发出请求之前进行规范化和清理。在向用户显示响应之前,还需要对其进行格式化。当然,这些请求中的大多数都是由后端代码完成的。但如果你看看Stripe或Paypal的预构建结账页面,它们也在使用规范化和净化的值进行前端集成:https://developer.paypal.com/docs/business/checkout/configure-payments/single-page-app


结论/我的看法

出于安全考虑,我总是希望后端尽可能简单。更少的代码(也称为端点)意味着更小的攻击面。更多的配置可能性意味着要付出更多的努力来确保应用程序的安全。此外,如果您有业务需求,需要从后端提供所有格式完美的服务,那么您可以编写另一个(微)服务来完成一些转换任务。示例用例可能是,如果你更喜欢后端代码而不是前端代码(想想你/你的团队的技能),如果你想部署很多不同的前端,并希望确保它们都使用一个真实的显示值来源,或者如果你需要满足监管要求,以确切地知道向用户提供了什么。

谢谢你的问题,我希望我已经为你自己的决定提供了一些指导。最后,你会一直希望自己选择了一种不同的方法…;)

为了消毒,出于安全原因,它必须在后端。Sanitisation关注的是确保您的网络表单中只有特定字段的值被接受。这就像一个专属俱乐部的客人名单。它不仅涉及字段(例如用户名),还涉及值(例如bobbycat或);DROP TABLE用户;)。因此,这是为了确保数据库的安全。

另一方面,规范化涉及在将数据存储到数据库之前对其进行转换。这就是你提到的例子:1000到1000,因为你在数据库中把它存储为没有小数的整数。

这个代码属于哪里?我认为没有明确的赢家,因为这取决于你的用例。

如果这是一个简单的问题,比如确保值是一个整数而不是字符串,那么您应该将其卸载到web表单(即前端),因为表单已经有一个";类型";属性来强制执行这些。

但想象一个更复杂的场景。假设你正在构建一个允许用户构建Facebook广告活动的应用程序(你的应用程序是第三方开发应用程序,如Smartly.io)。这意味着在用户点击"之前,必须填写大约30个表单字段;创建活动";。某些表单字段中的值会影响表单其他部分的有效性

在这种情况下,将至少一些验证放在后端可能是有意义的,因为为了确保有效性,后端需要运行一系列操作(如创建帖子,然后创建广告)。在前端对这些验证和规范化进行编码是没有意义的。

总之,这是一个你需要达到的平衡。将简单的东西卸载到前端,利用web API和表单验证。将更复杂的规范化步骤留给后端。

与此相关的是,如果您试图使用来自另一个服务的数据,然后将其转换为适合您在自己的数据库中存储信息的方式,则可以使用ETL(提取、转换、加载)的更广泛概念。在这种情况下,通常将其作为一个单独的存储库是一个好主意——使用Apache Airflow之类的东西来管理和可视化cron作业。

最新更新