【Laravel】FileMaker接続をGuzzleHttpで行う

# はじめに
Laravelでアプリを作成していて、DBはMySQLを使用してましたが、
既存システムの**FileMaker**との連携が必要だったので、
その時の学びをアウトプットします。

今回は**GuzzleHttp**を使用しました。

事前にPostmanやVScodeのThunderClientでのAPI接続確認してください！
またレスポンスの確認もしてください。

その上でコードに落とし込んだ内容です。

# 環境
・Laravel 8
・FileMaker Server 17

# 公式ドキュメント
基本的にはこちらを参照してます。
https://fmhelp.filemaker.com/docs/17/ja/dataapi/

# 前準備
必要な情報は以下。
・接続先URL
・データベース名
・レイアウト名（テーブル名みたいなもの）
・ユーザー名
・パスワード

これらの情報について直書きしているような記述をしてますが、
`.env`に記載し、`config`ファイルで読み込みし、
`config('filemaker.url')`みたいに読み込んでいます。


# ログインしtoken取得

公式ドキュメントにはヘッダー情報に
`Content-type`と`Authorization`とあります。
しかしBase６４でエンコードされた情報でうまくtokenが取得できなかったため
Basic認証で`POST`アクセスしました。
詳細は以下です。

```php

use GuzzleHttp\Client;

$path = {URL}/fmi/data/v1/databases/{DB名}/sessions;

$option = [
    'headers' => [
        'Content-type' => 'application/json',
    ],
    'auth' => [
        {ユーザー名},
　　　　　　　　　　　　　　　　{パスワード},
    ],
    'http_errors' => false, // アプリの仕様上つけました
];

$client = new Client();
$resJson = $client->request('POST', $path, $option)->getBody()->getContents();
$response = json_decode($resJson, true);
// エラー処理は割愛

$token = $response['response']['token'];
// このTokenを今後使用する。

```

# ログアウトしセッション破棄する

URLに破棄したい`token`を追加して
 `DELETE`メソッドで以下のようにアクセスする。

```php

$path ={URL}/fmi/data/v1/databases/{DB名}/sessions/ .　$token;

$option = [
    'headers' => [
        'Content-type' => 'application/json',
    ],
    'http_errors' => false,
];

$client = new Client();
$resJson = $client->request('DELETE', $path, $option)->getBody()->getContents();
$response = json_decode($resJson, true);
// エラー処理は割愛

```



# レコードを検索する
いくつか方法はあるが今回はURLに　`_find`をつける方法で行いました。
ポイントがいくつかあります。

まずはtokenを使用した認証方法ですが、ヘッダー情報に`Authorization`を追加し
`Bearer`のあとに`token`を追加します。

つぎにクエリですが`body`にjson形式でクエリ式を追加することで検索できます。
`POST`リクエストです。

```php

$path = {URL}/fmi/data/v1/databases/{DB名}/layouts/{テーブル名}/_find;

$option = [
    'headers' => [
        'Content-type' => 'application/json',
        'Authorization' => 'Bearer ' . $token,
    ],
    'http_errors' => false,
    'body' => '{"query": [
                     {"無効F": "="},
                ],
                "limit": "500"
               }',
];

$client = new Client();
$resJson = $client->request('POST', $path, $option)->getBody()->getContents();
$response = json_decode($resJson, true);

```

上のクエリはわかりずらいですが、`無効F`という項目に何も入っていないレコードを抽出してます。
逆に`無効F`という項目に`無効`と入っているものを抽出する場合は以下です。
`limit`についてですが、デフォルトでは１００のためそれ以上の場合は指定が必要です。

またクエリの部分のJSON形式をPHPのjson_encode()を使用したら
うまくいかなかったので直書きしてますm(__)m

```php
{"無効F": "=無効"}
```

# 単一のレコードを取得
ファイルメーカーのレコードIDがわかる場合はこの方法で取得できます。
URLにIDを指定します。
'GET'リクエストです。

```php

$path = {URL}/fmi/data/v1/databases/{DB名}/layouts/{テーブル名}/records/{ID};

$option = [
    'headers' => [
        'Content-type' => 'application/json',
        'Authorization' => 'Bearer ' . $token,
    ],
    'http_errors' => false,
];

$client = new Client();
$resJson = $client->request('GET', $path, $option)->getBody()->getContents();
$response = json_decode($resJson, true);

$item = $response['response']['data'][0]['fieldData'];

```

# レコードを作成する

ポイントは`body`に`fieldData`に項目名と値をJson形式で追加します。


```php

$path = {URL}/fmi/data/v1/databases/{DB名}/layouts/{テーブル名}/_find;

$option = [
    'headers' => [
        'Content-type' => 'application/json',
        'Authorization' => 'Bearer ' . $token,
    ],
    'http_errors' => false,
    'body' => '{"fieldData":
                     {
                      "名前": "' . $name . '",
                      "電話": "' . $tel . '",       
                      "住所": "' . $address . '",
                      },
               }',
];　// fieldDataには仮の値を指定してます。

$client = new Client();
$resJson = $client->request('POST', $path, $option)->getBody()->getContents();
$response = json_decode($resJson, true);

// レコード作成時にはidが返ってくる
$id = $response['response']['recordId'];

```

# さいごに
`認証`の記述の仕方がドキュメントの方法でうまくいかなかったり
`body`の`Json形式`がうまくいかずさまざまなエラーの対応して
どうにか完了することができました！

もっとスマートな方法があるかもですが、一旦うまくいった方法として載せております。