ClojureからECSにアクセスする「clj-aws-ecs」


making/clj-aws-ecs – GitHub

今作っているサービスで少し使ってみたので、メモしておきます。

広告

使い方は至って簡単で、

(use 'am.ik.clj-aws-ecs)
(def requester (make-requester "ecs.amazonaws.jp" "YOUR-ACCESS-KEY-ID" "YOUR-ACCESS-SECRET-KEY"))
(item-search-map requester "SearchIndex" "KEYWORD")

商品カテゴリーの指定(SearchIndex) – 商品検索(ItemSearch) – Amazon Web サービス

SearchIndex一覧については上記のページに書いています。

clj-aws-ecs | Clojars

clojars.orgにも登録されているので、project.cljに下記のように登録すれば簡単に使えるようになります。

[am.ik/clj-aws-ecs "0.1.0"]

ただ、ECSの戻り値がXMLで、item-search-mapの構造はXMLをそのままMapに変換した構造になっているため、その値を使って何かに利用する時に面倒なので、簡易的ですが、下記のようなコードを書いてXMLベースのMapから値を抜き出す処理を書きました。

(defn ecs-attr-value
  ([attrs tag] (ecs-attr-value attrs tag true))
  ([attrs tag first-only]
   (if (empty? attrs)
     nil 
     (let [attr (first attrs)
           attr-tag (:tag (first attrs))]
       (if (= tag attr-tag)
         (if first-only
           (first (:content attr))
           (:content attr))
         (recur (next attrs) tag first-only))))))
 
(defn ecs-item-attrs-parse
  [item attrs]
  (if (empty? attrs)
    item
    (let [attr (first attrs)]
      (def attr-value
        (cond
          (= (:tag attr) :ASIN) {:ASIN (first (:content attr))} 
          (= (:tag attr) :ItemAttributes) {:Title (ecs-attr-value (:content attr) :Title)} 
          (= (:tag attr) :SmallImage) {:SmallImage (ecs-attr-value (:content attr) :URL)} 
          (= (:tag attr) :MediumImage) {:MediumImage (ecs-attr-value (:content attr) :URL)} 
          (= (:tag attr) :LargeImage) {:LargeImage (ecs-attr-value (:content attr) :URL)} 
          (= (:tag attr) :DetailPageURL) {:DetailPageURL (first (:content attr))}))
      (recur (if (nil? attr-value) item (conj item attr-value)) (next attrs)))))
 
(defn ecs-item-parse [items xml-items] 
  (if (empty? xml-items)
    items
    (recur 
      (conj items (ecs-item-attrs-parse {} (:content (first xml-items)))) 
      (next xml-items))))
 
(defn ecs-item-search [search-index keywords]
  (ecs-item-parse [] (filter 
                       #(= :Item (% :tag))
                       (:content 
                         (first 
                           (filter 
                             #(= :Items (% :tag))
                             (:content (item-search-map 
                                         requester 
                                         search-index 
                                         keywords 
                                         {"AssociateTag" "example-22"
                                          "ResponseGroup" "Medium"}))))))))

関連記事