ruby-on-rails - 插入 ruby 变量和对象的动态 json 模板
问题描述
我们正在我们的应用程序中构建一个传出 webhook 功能。我们希望添加 webhook 的用户能够自定义发送的 json 有效负载。为此,我们需要一种允许将变量插入最终有效负载的语法。
示例:用户管理的模板:
{:id=>"%{id}", :message=>"%{message}", :badge=>"%{badge}"}
希望的输出:
{
"id": "f1ih5g3",
"message": "Thanks for your help",
"badge": {
"id": "M7nk8ojK",
"name": "Thanks Badge",
"points": 10,
}
}
因此,在上面的示例中,有一个主要的 webhook 对象,以及 和 的基本变量id
被message
插值并作为字符串返回。但是,当模板中包含对完整对象的引用时,我们还希望能够支持嵌套结构。当包含对完整对象的引用时,它应该返回该对象的 json 表示。
我们尝试使用 String#% 运算符,它适用于基本变量,但对于嵌套对象,它会产生如下字符串化版本:
{
"id": "f1ih5g3",
"message": "Thanks for your help",
"badge": "{:id=>\"M7nk8ojK\", :name=>\"Thanks Badge\", :points=>10}"
}
我探索了 RABL 和 Jsonnet,它们似乎并不真正支持动态模板(即由用户管理的模板)。
ERB 语法可以工作,但似乎不安全,因为任何任意 ruby 都可以包含在模板中。
解决方案
如果是我,我会选择这样的解决方案。我会收集用户可以在一个类下使用的变量并编写以下代码。也许我误解了代码,因为我无法完全预测问题。
require 'json'
require 'pry'
require 'securerandom'
class CustomerArea
ALLOWED_METHODS = %i[id message badge]
def self.id
SecureRandom.uuid
end
def self.message
"Lorem ipsum dolar sit amet"
end
def self.badge
{
id: SecureRandom.uuid,
name: "Foo",
points: 5
}
end
end
class Processor
def process(input)
json_object = JSON.parse(input, symbolize_names: true)
result = {}
json_object.each do |key, value|
extracts = value.match /\A%{insert_(?<field>\w+)}\z/
if extracts.nil?
result[key] = value
next
end
field = extracts[:field].to_sym
allowed_methods = CustomerArea.const_get(:ALLOWED_METHODS)
next unless allowed_methods.include? field
result[key] = CustomerArea.send(field)
end
result.to_json
end
end
customer_input = '{ "id": "%{insert_id}", "message": "%{insert_message}", "badge": "%{insert_badge}"}'
processor = Processor.new
puts processor.process(customer_input)
推荐阅读
- android - 如何在水平进度条android中设置进度
- python - 从主 SQL 表中的列创建新表
- python - 如何从 2 个不同的数据集中并排显示 seaborn 图?
- c++ - 带有非专业模板的 std::is_same_v
- android - ovpn文件与android集成
- javascript - Rails 在旧表单而不是模式上显示错误
- php - 使用 Laravel Eloquent 从数据库中获取两个日期之差等于一个值的记录
- events - Google Scripts:为什么我在使用 getEventSeriesById() 时总是返回空值?
- swift - 任何模型中都没有 NSEntityDescriptions 声明 NSManagedObject 子类你加载你的 NSManagedObjectModel 了吗?
- ios - iOS 的 Corodva 应用程序构建失败 ** 存档失败 **