【Laravel】API呼び出し実装 BカートAPI編

自サイトやシステムから、他のサイトの情報を利用するためにAPIを呼び出す機能はよく要望頂きますので、今回はLaravelを使ってAPI呼び出しを行います。

サンプルとしてちょうど案件対応しているBカートのAPIを利用します。

Laravelは8.xで確認していますが、6,7辺りでも問題なく動作します。

LaravelでAPIを呼び出す方法

HTTPリクエストの生成など面倒な処理はすべてパッケージにお任せします。

Laravel公式ドキュメントではGuzzleの利用が推奨されているため、こちらを利用します。

Laravel8.x HTTP クライアント

Guzzleインストール

デフォルトでもインストールされているはずですが、何かの拍子に削除してしまっていた場合は、下記コマンドで再インストールできます。

composer require guzzlehttp/guzzle

これでguzzleの準備ができました。Laravelではguzzleをそのまま使うのではなく、HTTPファサードが提供する「get」「post」「put」「patch」「delete」メソッドを介して利用します。

基本的なリクエスト

公式ドキュメントに記載されているソースはHTTPファサードを利用したものですが、guzzleをそのまま利用する方法も併記していきます。

Guzzleの公式ドキュメント

Curl

まずはcurlコマンドでリクエストを投げる場合のサンプル

curl --location --request GET https://api.bcart.jp/api/v1/orders' \
--header 'Accept: application/json' \
--header 'Authorization: Bearer {{key}}'

このリクエストをソースで表現していきます。

curl: (1) Protocol “‘https” not supported or disabled in libcurl

公式マニュアルには上記で記載されていますが、windowsのコマンドプロンプトなどでは上記のコマンドをそのまま実行するとエラーになります。シングルクォーテーションで囲っていることが原因ですので、全てダブルクオーテーションに書き換えます。

curl --location --request GET "https://api.bcart.jp/api/v1/orders" \
--header "Accept: application/json" \
--header "Authorization: Bearer {{key}}"

ファサード

Laraveお薦めのファサードを利用する方法

use Illuminate\Support\Facades\Http;

class BcartAPI
{
    public static function getOrders(){
            $response = Http::accept('application/json')
                ->withToken(config('app.bcart_key'))
                ->get(
                'https://api.bcart.jp/api/v1/orders', [
                'limit' => '100',
            ]);

            if($response->successful()){
                return json_decode($response->getBody(), true);
            }else{
                throw new \Exception('ERROR response:'.$response->status());
            }
}
}

LaravelのHTTPクライアントラッパーは、クライアントまたはサーバのエラー(サーバからの「400」および「500」レベルの応答)で例外を投げません。

successful、clientError、serverErrorメソッドを使用して、これらのエラーのいずれかが返されたかどうかを判定して処理する必要があります。

accept

レスポンスとして想定するコンテンツタイプを指定します

withToken

AuthorizationヘッダにBearerトークンを追加したい場合に利用します。

get

エンドポイントを指定します。リクエストパラメータとして付与するものは第二引数に配列で指定します。サンプルコードだとlimit=100の部分になります。

Guzzleを直接利用

ファサードなんか使わん!Guzzleをそのまま使うんだ!という方法

use GuzzleHttp\Client;

class BcartAPI
{

    public static function getOrders(){
        $client = new Client();
        try{
            $response = $client->request(
                'GET',
                'https://api.bcart.jp/api/v1/orders?limit=100',
                [   'headers' => [
                    'Accept'     => 'application/json',
                    'Authorization'      => 'Bearer '.config('app.bcart_key'),
                    ],
                    'http_errors' => false //エラーも通す指定
                ],

            );

            if($response->getStatusCode() === 200){
              return json_decode($response->getBody(), true);
            }else{
               throw new \Exception('ERROR response:'.$response->getStatusCode());
            }
}
}

Guzzleの場合は、http_errorsをfalseとするとレスポンスコードが400や500の場合でも処理を継続します。そのため、22行目でレスポンスコードが200以外はエラー処理をしています。

個人的にはLaravelのHTTPファサードを利用した方がコードが見やすいので、こちらを採用していきます。

これで無事リクエストを投げることはできるようになりました。

レスポンスデータの処理

リクエストを投げたらレスポンスが返ってきますので、データに格納するなどの手続きが必要になりなす。

APIを提供している会社様であれば、レスポンスデータのインターフェースについてもドキュメントを提供しているはずですのでしっかりと確認しましょう。

ドキュメントと併せて、実際のレスポンスデータをログなどに出力して確認することも重要です。

例えば、こちら

ordersレスポンスデータ定義

公式のドキュメントとしてレスポンスデータの物理名が定義されています。

tanoってなんだろう、、、

と思いながらコーディングしてみましたが、実行するとエラーになりました。

Undefined index: tano_last_name

tanoなんて知りませんとのこと。そこで実際のデータをログ出力した結果がこちら

'tanto_last_name' => 'B',
'tanto_first_name' => 'カート',
'tanto_last_name_kana' => 'ビー',
'tanto_first_name_kana' => 'カート',

「tano」ではなく「tanto」でした。

マニュアルを確認することも重要ですが、実際のデータも見ながらコーディングした方がイメージがつきやすく作業が捗る気がします。

レスポンスデータの格納

データ型に合わせて、格納処理を行います。サンプルにしたordresAPIhは受注情報が配列で返却されますので、ループして受注情報を作成していきます。

       $data = json_decode($response->getBody(), true);
       foreach($data['orders'] as $order_record){
           $order = new Order();
           $order->b_id = $order_record['id'];
           $order->b_code = $order_record['code'];
           $order->price = $order_record['total_price'];
           $order->ordered_at = $order_record['ordered_at'];
           $order->save();
       }

かなり大雑把な処理の仕方ですがとりあえず動きはします。(このまま動かすと同じ受注番号が重複登録されていきますが)

処理については、データの特性に合わせてコーディングをしていきましょう。

まとめ

今回はLaravelから外部のAPIを利用する方法を解説いたしました。サイトの機能を拡張していく上ではAPIの利用は欠かせないものとなりますのでぜひ参考にしてみたください。

マニュアルが全て正しいとも限らないので、困ったら実際のデータを出力しながら進めていくことも重要ですね。

コメントを残す