Laravel Http クライアントで、Gzipのデータを取得したい

  • このエントリーをはてなブックマークに追加
  • Pocket
  • LINEで送る

こんばんは、ウチイダです。

Amazon Ads API を利用して、広告費用を最適化するアプリケーションの開発をご依頼いただきました。

ドキュメントが今のところ英語しかないので、頑張って読み解きつつ進めています。

https://advertising.amazon.com/API/docs

LaravelでAmazon Ads APIとの通信部分を実装しているなかで、広告パフォーマンスのレポートデータをダウンロードする部分で少し苦労したのでメモしておきます。

Amazon Ads API では、クリック数や広告経由の売り上げなどの情報を取得するために、以下の手順を踏む必要があります。

  1. レポートデータの生成をリクエスト
  2. 最大15分ほど、レポートデータが生成されるのを待つ
  3. レポートデータが生成されたら、Amazon S3からダウンロードする

3でダウンロードされるデータがgzipで圧縮されていたので、うまくレスポンスを受け取るのに少し工夫が必要でした。

ちなみに、手順1, 2はLaravel Httpのドキュメントを見ながら結構簡単に実装できました。

https://readouble.com/laravel/9.x/ja/http-client.html

実際にうまく動作したコードは、以下のような感じです。

// 冒頭で、Http ファサードを読み込んでおく
use Illuminate\Support\Facades\Http;

$response = Http::
    withHeaders([
    'Content-Type' => 'application/json',
    'Amazon-Advertising-API-ClientId' => 'CLIENT_ID', // あらかじめ取得したClient IDを設定
    'Amazon-Advertising-API-Scope' => 'PLOFILE_ID', // あらかじめ取得したProfile IDを設定
])
    ->withOptions(['decode_content' => 'gzip']) // ★gzip形式での受け取りする
    ->withToken('ACCESS_TOKEN') // あらかじめ取得したアクセストークンを設定 WithToken() がBearer の記述など行ってくれる
    ->get("https://advertising-api-fe.amazon.com/v2/reports/{$reportId}/download"); // あらかじめ発行リクエストしたレポートのIDを設定

dump($response->body()); // gzip のバイトデータそのまま表示してみる
dump(gzdecode($response->body())); でコードしてもともとのデータを表示する

downloadのエンドポイントは、存在するレポートデータのIDに対してリクエストされたら、リダイレクトしてAmazonS3 バケットに配置されたデータを返してくれます。

Content-typeはapplication/jsonにしつつ、gzipのデータを取得するように設定する必要があります。

ポイントはwithOptions()でgzipのデータを受け取ることを記述している点です。

‘decode_content’ で指定できるのですね。

この設定値はLaravelのドキュメントには記載されていなくて、Guzzle のドキュメントを見る必要がありました。

https://docs.guzzlephp.org/en/stable/request-options.html#decode-content

ちなみに、ヘッダー内に書く場合は以下のようになります。

// 冒頭で、Http ファサードを読み込んでおく
use Illuminate\Support\Facades\Http;

$response = Http::
    withHeaders([
    'Content-Type' => 'application/json',
    'Amazon-Advertising-API-ClientId' => 'CLIENT_ID', // あらかじめ取得したClient IDを設定
    'Amazon-Advertising-API-Scope' => 'PLOFILE_ID', // あらかじめ取得したProfile IDを設定
    'Accept-Encoding' => 'gzip' // ★ここにgzipを指定
])
    ->withToken('ACCESS_TOKEN') // あらかじめ取得したアクセストークンを設定 WithToken() がBearer の記述など行ってくれる
    ->get("https://advertising-api-fe.amazon.com/v2/reports/{$reportId}/download"); // あらかじめ発行リクエストしたレポートのIDを設定

withOptions() がなくなってチェインするメソッドが減ったので、今回の場合であればこっちの方がすっきりします。

withToken()も、Bearer の記述をコード内に書けばwithHeaders() に含めることができるので、もっとまとめてしまうこともできます。

ウチイダ的にはwithToken() を使う方が楽なので、このままにしています。

以上です。あなたのお役に立てれば幸いです。

  • このエントリーをはてなブックマークに追加
  • Pocket
  • LINEで送る

SNSでもご購読できます。

コメントを残す

*