HitoHana(ひとはな)の舞台裏

HitoHana(ひとはな)運営の舞台裏をご紹介いたします!

RMSのAPIをRubyで実装したい 3/3

前回のブログより

新人の田中です。この記事ではRMSの受注APIをRailsのアプリケーションに導入した事例を紹介しています。
前回、前々回はRMSのAPIをRubyで使えるようにコードを書いてきました。
今回はこのシリーズの締めくくりとして、前回作成したAPIのRubyのラッパーと、ひとはなのアプリケーションをつなげるためのコードを書いていきます。

backstage.hitohana.tokyo

まずはいつものように完成形をイメージしてみる

Proxyパターンを使って実装します。ですので以下の条件を満たすようなコードを考えていきます。

  • アプリケーションの注文モデルのインスタンス(order)の情報を保持する。
  • RMSのAPIを使用して楽天側の情報にアクセスできる。
  • アプリケーションの注文モデルのメソッドはそのまま使える。
# orderはアプリケーションで使用している注文モデルのインスタンス
r_order = Rms::OrderProxy.new(order)

r_order.rakuten_info
# => 楽天の注文情報

# do_somethingメソッドはもともとの注文モデルのインスタンスメソッド
r_order.do_something
# => order.do_somethingと同じ戻り値

これだけなら簡単なんだけど

以上の条件を満たせるようにProxyオブジェクトを作ってみました。

module Rms
  class OrderProxy
    def initialize(order)
      @order = order
    end

    def method_missing(method_name, *args)
      @order.send method_name, *args
    end

    def rakuten_info
      return nil unless rakuten_order?
      # Rms::Order.get_orderについては前回の記事を参照。
      Rms::Order.get_order(
        is_order_number_only_flag: false,
        order_number: [@order.platform_number],
      )
    end

    private

    def rakuten_order?
      @order.platform_name == '楽天'
    end
  end
end

たしかにこれだけでもちゃんと動くんですけど、

なんかつまんない

ので、APIを呼び出す部分に関してもう少し工夫してみることにしました。

イケてないところは?

実際にAPIを使う際に不便に思っていることを挙げてみて、そこから機能を追加していくことにします。

不便その1:レスポンスの構造

本家のAPIのレスポンスの構造の問題なんですが、ネストが深くて、実際に業務で仕様する部分に到達するためには複数のメッセージを投げないといけません。

response = Rms::Order.get_order(args)
# => #<Hashie::Mash>

# 実際に注文情報を得るためにはこのように複数のメッセージを投げないといけない
order_info = response.get_order_response.return.order_model
# => 楽天の注文情報

不便その2:エラーハンドリング

Soap通信が失敗したり、RMSのシークレットキーの有効期限切れなどの際に発生したエラーを検知する機能がありません。

機能を追加しよう

なので、以下の機能を追加することにしました。

  • APIの生のレスポンスそのままを返すのではなく、業務で使う部分だけを抽出して返します。
  • ログを出力します。

ただ、これらの機能を普通にくっつけても

つまんない

ので、以前から気になっていたgemを使ってみることにしました。

github.com

これなら有名なRackのように再利用可能なMiddlewareを作って、その組み合わせでサービスを構成できます。

次回は

Middlewareを実装してこのシリーズを締めたいと思います。

さっき今回でこのシリーズを締めると言ったな。あれは嘘だ。

おわりに

HitoHana(ひとはな)では、仕事が大好きで個性的なエンジニアを大募集しています!

www.wantedly.com