はじめに
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
とあります。
しかしBase64でエンコードされた情報でうまくtokenが取得できなかったため
Basic認証でPOST
アクセスしました。
詳細は以下です。
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
メソッドで以下のようにアクセスする。
$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
リクエストです。
$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
についてですが、デフォルトでは100のためそれ以上の場合は指定が必要です。
またクエリの部分のJSON形式をPHPのjson_encode()を使用したら
うまくいかなかったので直書きしてますm(__)m
{"無効F": "=無効"}
単一のレコードを取得
ファイルメーカーのレコードIDがわかる場合はこの方法で取得できます。
URLにIDを指定します。
'GET'リクエストです。
$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形式で追加します。
$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形式
がうまくいかずさまざまなエラーの対応して
どうにか完了することができました!
もっとスマートな方法があるかもですが、一旦うまくいった方法として載せております。