如何在Grape/Rails API中通过函数设置参数的type与desc属性
问题解答
该需求完全可以实现,核心要注意Grape的params块是类加载阶段执行的类上下文DSL,所以自定义方法需要能在类作用域被访问到即可。
自定义函数的放置方案
场景1:仅当前API类使用
直接在当前API类中定义类方法即可,参考改造后的代码:
class MyObject < Grape::API # 先定义类级别的自定义方法 def self.custom_field_type(cf) # 示例逻辑:根据字段后缀匹配对应Grape支持的类型 case cf when /_int$/ then Integer when /_float$/ then Float when /_bool$/ then Grape::API::Boolean when /_dt$/ then DateTime else String end end def self.custom_field_desc(cf) # 示例逻辑:直接读取模型的i18n翻译作为描述 CustomField.human_attribute_name(cf) end desc 'Update a MyObject.' params do requires :id, type: Integer, desc: 'MyObject ID.', documentation: {param_type: 'body'} optional :title, type: String, desc: 'MyObject Title.', documentation: {param_type: 'body'} optional :custom_field_attributes, type: Hash, documentation: {param_type: 'body'} do CustomField.column_names.each do |cf| next unless cf.include? 'custom_' optional cf.intern, type: custom_field_type(cf), # 直接调用类方法即可 desc: custom_field_desc(cf) end end end patch do # 原有业务逻辑 end end
场景2:多个API类复用该方法
可以抽成公共的工具模块,按Rails项目惯例放在app/api/concerns/param_custom_field_helpers.rb:
module ParamCustomFieldHelpers def custom_field_type(cf) # 同上的类型判断逻辑 end def custom_field_desc(cf) # 同上的描述生成逻辑 end end
然后在需要用到的API类中用extend引入模块即可:
class MyObject < Grape::API extend ParamCustomFieldHelpers # 剩余原有代码 end
注意事项
- 上述写法中
CustomField.column_names是类加载阶段执行的,如果后续CustomField表结构有修改,需要重启服务才能加载到最新的字段列表。 - 布尔类型不要直接使用
Boolean、TrueClass/FalseClass,要使用Grape提供的Grape::API::Boolean类型,避免参数解析异常。
内容的提问来源于stack exchange,提问作者LiKaZ
相关产品推荐
相关产品推荐

