You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于HTTParty的Shopify Recharge API封装优化问题咨询

需求实现方案

1. 支持全局配置api_token

核心思路是把token配置从常量改为模块级的可写属性,同时调整HTTParty的header生成逻辑,从类加载阶段固定值改为每次请求动态获取最新token:

  • 在RechargeAPI模块层面定义可读写的api_token存取方法
  • 重写Client类的default_options方法,动态合并token到请求头,避免类加载时就固定header的问题

2. 返回Customer类实例而非OpenStruct

不需要继承Struct,可通过自定义初始化方法+动态属性定义实现,既不打破原有继承关系,也能支持属性直接访问:

  • 在Customer类中定义初始化方法,接收API返回的属性哈希
  • 初始化时动态生成对应属性的存取方法,直接把属性值挂载到实例上

完整优化后代码

module RechargeAPI
  require 'httparty'
  BASE_URI = 'https://api.rechargeapps.com'

  # 全局配置存取器
  class << self
    attr_accessor :api_token
  end

  class Client
    include HTTParty
    base_uri BASE_URI
    default_timeout 10 # 基础超时配置

    # 动态生成请求配置,每次请求都会拉取最新的api_token
    def self.default_options
      super.merge(
        headers: { 'X-Recharge-Access-Token' => RechargeAPI.api_token }
      )
    end

    # 公共响应错误处理,所有资源类复用
    def self.handle_response(response)
      case response.code
      when 200 then return
      when 401 then raise "Recharge API 认证失败:请检查api_token配置"
      when 429 then raise "Recharge API 触发限流,请降低请求频率"
      else raise "Recharge API 请求错误:状态码#{response.code},错误信息#{response.message}"
      end
    end
  end

  class Customer < Client
    def initialize(attributes = {})
      attributes.transform_keys(&:to_sym).each do |key, value|
        # 动态定义属性存取方法,只定义一次避免重复开销
        self.class.attr_accessor key unless self.method_defined?(key)
        send("#{key}=", value)
      end
    end

    def self.search(params)
      response = get('/customers', query: params)
      handle_response(response)
      from_json(response.body)
    end

    def self.find(params)
      search(params).first
    end

    def self.all
      # 可扩展分页逻辑,这里暂时保留原有逻辑
      response = get('/customers')
      handle_response(response)
      from_json(response.body)
    end

    def self.from_json(customers_json)
      customers = JSON.parse(customers_json).dig('customers')
      customers.map { |customer| new(customer) }
    end
  end
end

使用示例

# 全局设置token,随时设置随时生效
RechargeAPI.api_token = '你的实际接口token'

# 调用接口,返回的是RechargeAPI::Customer实例
customer = RechargeAPI::Customer.find(shopify_customer_id: 5363543224286)
puts customer.class # 输出 RechargeAPI::Customer
puts customer.billing_address1 # 可直接访问所有API返回的属性

其他可落地优化建议

  • 公共逻辑抽象:把search、find、all、from_json这类所有资源类都会用到的方法抽到父类Client中,后续新增Subscription、Address等资源类时直接继承即可,无需重复编写逻辑
  • 分页支持:Recharge API默认分页返回30条数据,可给all方法封装自动翻页逻辑,一次性返回全量数据
  • 重试机制:针对网络抖动、限流场景添加请求重试逻辑,可配合retriable gem实现指数退避重试
  • 日志支持:添加请求/响应日志开关,方便调试时排查接口调用问题
  • 参数校验:接口调用前增加必填参数校验,提前拦截非法请求避免浪费网络开销

内容的提问来源于stack exchange,提问作者Artyrcheek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 19:24:02