Laravel+GuzzleでホットペッパーAPIを叩いてレストラン情報を取得する方法

こんにちは、JeffTechです。

# この記事で実現できること
- Laravel+Guzzleの開発環境構築
- HotpepperAPIでレストラン情報を取得する

# 説明
今回はLaravel＋GuzzleでホットペッパーAPIを叩いてレストラン情報を取得していきたいと思います。

# 開発環境
- Laravel: 6.2
- Guzzle: 7.2

# 実装の流れ
1. リクルートWEBサービスへ新規登録 
1. Laravelプロジェクトの作成
1. Guzzleのインストール
1. Guzzleを使う前の準備
1. Route
1. Controller
1. View

# 実装


## 1. リクルートWEBサービスへ新規登録
無料かつメールアドレスのみで簡単に登録できるので、[こちらよりアクセス](https://webservice.recruit.co.jp/doc/hotpepper/reference.html)して、新規登録ボタンをクリックして登録してください。
※記事執筆当時は左上辺りに新規登録ボタンがありました。

新規登録が終わると登録したメールアドレスにAPIキーを送信してくれるので、大切に保存しておいてください。後ほど使用します。


## 2. Laravelプロジェクトの作成

```bahs
$ composer create-project --prefer-dist laravel/laravel hotpepperApi "6.*"
```
これで`hotpepperApi`というLaravelプロジェクトが作成できました。


## 3. Guzzleのインストール
Guzzleとは、PHPのHTTPクライアントです。
とても簡単にHTTPリクエストが送信でき、APIとの連携を簡単にしてくれます。
[公式ドキュメント](https://docs.guzzlephp.org/en/stable/)

では、composerを使ってインストールしていきます。
`hotpepperApi`ディレクトリで下記のコマンドを実行してください。

```bash
$ composer require guzzlehttp/guzzle
```
コマンドが実行されたあと`composer.json`の`require`の中を見ると`"guzzlehttp/guzzle": "^7.2",`となっているのがわかると思います。
インストールした時期によってバージョンが多少違うかもしれませんが、特に問題はありません。


## 4.Guzzleを使う前の準備
先程取得したAPIキーはとても大事な情報なので、`.env`に記述していきます。

`.env`の最後の行で構いませんので、以下を追加してください。

```
MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"

HOTPEPPER_API_KEY=1111a1a1aaaa1a11 // ここにAPIキーを記述
```

次に、これをconfigメソッドで呼び出せるようにしたいので、`configディレクトリ`配下に`hotpepper.php`を作成して、編集していきます。

ちなみに、envメソッドでも`.env`の内容は呼び出せるのですが、本番環境で`php artisan config:cache`コマンドを実行するとコントローラやモデルでenvメソッドを使用していると`.env`の内容を読み込まなくなります。
そのため、コントローラやモデルで`.env`の内容を取得したい場合は、configメソッドを使用していきます。

```bash
$ touch config/hotepper.php
```

```php:hotpepper.php
<?php

return [
    'api_key' => env('HOTPEPPER_API_KEY')
];
```
これで、コントローラやモデルなどで`config('hotpepper.api_key')`とすることでAPIキーを取得できるようになりました。


## 5. Route
先にルーティングを設定しておきます。

```php
<?php

Route::get('/', 'HotpepperController@index');
```
`http://127.0.0.1:8000`にアクセスされた場合、これから作成する`HotpepperController`の`indexメソッド`が走るようになります。


## 6. Controller
コントローラを作成していきます。

```bash
$ php artisan make:controller HotpepperController
```
`app/Http/Controllers/HotpepperController.php`が下記の内容で作成されます。

```php:HotpepperController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class HotpepperController extends Controller
{
    //
}
```
先程のルーティングで`indexメソッド`を走らせるような処理にしたので、`indexメソッド`を作成し、ほとんど[Guzzleの公式ドキュメント](https://docs.guzzlephp.org/en/stable/![スクリーンショット 2021-03-16 23.53.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/658326/be22fe75-af53-bfb2-2b8b-4fb8aaa7af41.png)
)のままですが、コントローラを編集していきます。

```php:HotpepperController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use GuzzleHttp\Client; // ここを追記

class HotpepperController extends Controller
{
    // ーーここから追記ーー
    // HTTPリクエストを送るURL
    private const REQUEST_URL = 'http://webservice.recruit.co.jp/hotpepper/gourmet/v1/';

    // APIキー
    private $api_key;

    public function index()
    {
        // インスタンス生成
        $client = new Client();

        // HTTPリクエストメソッド
        $method = 'GET';

        // APIキーを取得
        $this->api_key = config('hotpepper.api_key');

        // APIキーや検索ワードなどの設定を記述
        $options = [
            'query' => [
                'key' => config('hotpepper.api_key'),
                'keyword' => '新宿',
                'count' => 10,
                'format' => 'json',
            ],
        ];

        // HTTPリクエストを送信
        $response = $client->request($method, self::REQUEST_URL, $options);

        // 'format' => 'json'としたのでJSON形式でデータが返ってくるので、連想配列型のオブジェクトに変換
        $restaurants = json_decode($response->getBody(), true)['results'];

        // index.blade.phpを表示する
        return view('index', compact('restaurants'));
    }
    // ーーここまで追記ーー
}
```
処理の内容はほとんどコメントで記述しておきました。
今回ホットペッパーのグルメサーチAPIを使用するので、[ドキュメント](https://webservice.recruit.co.jp/doc/hotpepper/reference.html)を見ると、
リクエストURLが載っていますので、それをそのまま定数に入れましょう。

![スクリーンショット 2021-03-16 23.54.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/658326/4bf7c036-a5c6-8ede-2c17-657258de1be0.png)

検索クエリをみて、必須である`key(APIキー)`を`query`の中に入れます。
この時`query`が配列になっているので気をつけてください。
そして、今回は新宿というキーワードに当てはまるレストラン情報を取り出したいので、`keyword`を新宿で設定していきます。
あとは何件取得するのかやレスポンス形式を検索クエリを参考に`query`の中に記述しています。

![スクリーンショット 2021-03-16 23.54.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/658326/35e735ee-1f2c-759b-9d25-204588d1341e.png)
![スクリーンショット 2021-03-16 23.56.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/658326/b0ec695f-a767-6299-8255-8ce49254365c.png)
![スクリーンショット 2021-03-16 23.55.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/658326/0649c9be-aedf-1abd-5f07-9257d66fea74.png)



## 7. View
`HotpepperController.php`の中で、`resources/views/index.blade.php`を表示させるようにしているので、作成と編集をしていきます。

```bash
$ touch resources/views/index.blade.php
```

```html:index.blade.php
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>ホットペッパーAPI</title>
</head>
<body>
    <table border="1">
        <tr>
            <th>店舗名</th>
            <th>営業時間</th>
        </tr>
        @for ($i = 0; $i < $restaurants['results_returned']; $i++)
            <tr>
                <td><a href="{{{ $restaurants['shop'][$i]['urls']['pc'] }}}">{{{ $restaurants['shop'][$i]['name'] }}}</a></td>
                <td>{{{ $restaurants['shop'][$i]['open'] }}}</td>
            </tr>
        @endfor
    </table>
</body>
</html>
```
`index.blade.php`では、店舗名をリンクにして店舗ページへ飛べるようにしたものと、営業時間を出力するようにしてあります。
これも、[ドキュメント](https://webservice.recruit.co.jp/doc/hotpepper/reference.html)のレスポンスフィールドを見ながら、該当の場所をコントローラで連想配列にした`$restaurants`から抜き出している感じです。
![スクリーンショット 2021-03-17 0.00.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/658326/749c9a80-3e43-838d-a0a3-4998904a8996.png)



# 最後に
取得する情報等を変えたりすることで様々なことができそうですね！
とりあえずはこれでいい感じではないでしょうか？

少しでも役に立った！という時は、いいねをポチッとして
フォローしてくださると嬉しいです、、、笑

役に立たなかった時は、怒らないでコメント頂けますと幸いです笑

Twitterもやってますので、よかったら見てみてくださいね！
https://twitter.com/jefftechsaku