楽天市場のAPIマニュアルを信じるな!画像更新APIでドはまりした事。
楽天市場のAPIマニュアルを信じるな!
自作システムも順調に組みあがり、現在運用テスト中です。
マニュアルも書かなくてはいけないのでまだまだやる事沢山ありますが、自社テストではヤバいくらい快適に商品情報の更新が出来ています。
画像も一緒に更新する仕組みなので、情報を整理してAPI出品ボタンを押すだけですべての出品が出来る快適さが、旧作のAccessなどにはない利便性だと思います。
とまぁ、宣伝はこれくらいにして【楽天市場のAPIマニュアルを信じるな】の本題に移ろうと思います。
今回作成したシステムで、ずっと手こずっていたパーツがありました。
それは、画像のUPDATEとINSERT!
file_get_contents で作成して更新する事は出来ていたのですが、【curl】で書きたいなぁと色々弄っていました。
マニュアルの間違いに気づいたのはその時です。
嵌った画像のAPI更新
楽天市場のマニュアルには次のように書いてあります。
POST /public/1.0/cabinet/file/insert HTTP/1.1
Host: 127.0.0.1:8011
Proxy-Connection: keep-alive
Content-Length: 999999 --サイズ
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.111 Safari/537.36
Origin: chrome-extension://hgmloofddffdnphfgcellkdfbfbjeloo
Content-Type: multipart/form-data; boundary="【boundaryの文字列】"
Accept: /
Accept-Encoding: gzip,deflate
Accept-Language: ja,en-US;q=0.8,en;q=0.6
------【boundaryの文字列】
Content-Disposition: form-data; name="xml"
<?xml version="1.0" encoding="UTF-8"?>
<request>
<fileInsertRequest>
<file>
<fileName>ZZZ</fileName>
<folderId>0</folderId>
<filePath>img136281.jpg</filePath>
<overWrite>true</overWrite>
</file>
</fileInsertRequest>
</request>
------【boundaryの文字列】
Content-Disposition: form-data; name="file"; filename="Chrysanthemum.jpg"
Content-Type: image/jpeg
[画像ファイルのバイナリデータ]
------【boundaryの文字列】--
この姿に形成して画像のINSERTを試みるのですが、エラー。
返ってくるのはこんなのばかりです。
<?xml version="1.0" encoding="UTF-8"?>
<result>
<status>
<interfaceId>cabinet.file.insert</interfaceId>
<systemStatus>NG</systemStatus>
<message>SystemError(101)</message>
<requestId>00b38eb4-73f8-4281-be38-f0daf1b7bd30</requestId>
<requests/>
</status>
</result>
<?xml version="1.0" encoding="UTF-8"?>
<result>
<status>
<interfaceId>cabinet.file.insert</interfaceId>
<systemStatus>NG</systemStatus>
<message>Request data is wrong format</message>
<requestId>5509b199-4eab-4f7c-ad84-75ed31b672bf</requestId>
<requests/>
</status>
</result>
multipart/form-dataって
そもそもマルチパートを形成してアップロードするというのは今まで経験がありません。画像のアップロードとかマルチパートで更新されますが、Laravelとかが勝手にやってくれるものなので、意識はしていないんですよね。
と言う事で、改めて勉強し直してみました。
【boundaryの文字列】を指定して、【boundaryの文字列】によってデータを区分けして送信する方法。
ざっくりまとめるとコレがマルチパート形式です。
そういった意味では、上のマニュアルは間違えているようには見えません。
まぁマニュアルですしね。大間違いはないですよね。
ではなぜ同じ形を作っても更新に失敗するか。それはマルチパート形式の従わなくてはいけないルールにあります。
マルチパート形式のルール
- Content-Typeの境界線は 【--】で指示をする。
- Content-Typeの境界線終了は 【--】で指示をする。
つまりは、次のような形成です。
POST /public/1.0/cabinet/file/insert HTTP/1.1
Host: 127.0.0.1:8011
Proxy-Connection: keep-alive
Content-Length: 999999 --サイズ
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.111 Safari/537.36
Origin: chrome-extension://hgmloofddffdnphfgcellkdfbfbjeloo
Content-Type: multipart/form-data; boundary="【boundaryの文字列】"
Accept: /
Accept-Encoding: gzip,deflate
Accept-Language: ja,en-US;q=0.8,en;q=0.6
--【boundaryの文字列】
Content-Disposition: form-data; name="xml"
<?xml version="1.0" encoding="UTF-8"?>
<request>
<fileInsertRequest>
<file>
<fileName>ZZZ</fileName>
<folderId>0</folderId>
<filePath>img136281.jpg</filePath>
<overWrite>true</overWrite>
</file>
</fileInsertRequest>
</request>
--【boundaryの文字列】
Content-Disposition: form-data; name="file"; filename="Chrysanthemum.jpg"
Content-Type: image/jpeg
[画像ファイルのバイナリデータ]
--【boundaryの文字列】--
------【boundaryの文字列】でも良いのですが、この形を正確に表記すると次の様になります。
ハイホン2つが飛び出たものがバウンダリ文字列になっているわけですね。
楽天市場マニュアルの間違い
1. 誤認表記を誘発するバウンダリ文字列の表記方法
○ Content-Type: multipart/form-data; boundary="【----boundaryの文字列】"
2. なぜか無用のスペースが入っている区切りのスタート
○ ------【boundaryの文字列】
いやぁ~、そりゃマニュアルの形をそっくり形成しても更新失敗するわけですよ。
まとめ
正解は次の2パターンです。
正解は次の2パターンだったみたいです。 Content-Type: multipart/form-data; boundary="----【boundaryの文字列】" ------【boundaryの文字列】 Content-Type: multipart/form-data; boundary="【boundaryの文字列】" --【boundaryの文字列】
ここだけ抑えて置けばマルチパートはそれほど難しいものではありません。
それにしても、マニュアルが信用できないとは...ショックでした。

