0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

FileMaker Data API を使う 2025 年版 vol.4

Last updated at Posted at 2025-02-07

 FileMaker Data API を使う 2025 年版 vol.3 から続きます。

サンプルデータの作成は FileMaker Data API を使う 2025 年版 vol.1 を参照してください。

利用環境

 以下の環境を前提に説明しています。

  • Claris FileMaker Pro 21.1.1.41 macOS
  • Claris FileMaker Server 21.1.1.40 Ubuntu 22(AMD)
  • サーバ: Ubuntu 22.04.5 LTS
  • SSL 証明書
  • リクエストする側のサーバ(任意)

 開発段階では、以下を使用した方が楽でしょう。

  • Postman Version 11.30.0

今回のシナリオ

 FileMaker Data API のレコード操作には、いくつかのリクエストがあります。また、一つのリクエストでも、いくつかのパターンがあります。
今回は、その中で、「records - Get Records」を取り上げますが、これにもいくつかのパターンがありますが、以下のようなシナリオを考えてみました。

  1. ログイン
  2. (何らかの処理があり、リンクでページ遷移した想定)
  3. セッションの検証
  4. レコード取得
  5. (何らかの処理)
  6. ログアウト

 「何らかの Web ページ/アプリケーション にログインし、トップページから、レコード取得ページに遷移して、フィルタ操作やダウンロード等の操作をユーザが行い、ログアウトした」というようなシナリオで進めたいと思います。

事前準備

 FileMaker Data API でリクエストするレイアウトはリクエストごとに必要なフィールドを並べたものを用意しましょう。
FileMaker Pro/Go で使用中のレイアウトを使用すると、レスポンスに不要なデータも含まれることになりデータ転送量の無駄になります。また、ポータルが含まれたレイアウトは、レスポンスが複雑になります。

レイアウトは必要最小限のフィールドのみを配置する

 これを鉄則にしてください。レイアウトを見せるわけではないので、何の装飾もないただ、雑にフィールドを配置したものでまったく問題ありません。

取得するデータの想定

 作成したデータは、1,375 件の STATCAST の PLAYER BATTING の Leaderboard のデータです。42 フィールドありますが、「player_batting」テーブルオカレンスを元にして、以下のフィールドに限定して、レイアウトを作成します。
 (テーブルオカレンスは、元のテーブルオカレンスを複製し、用途ごとに作成することを推奨しますが、ここではそのまま使用しています。)

  • last_name_ first_name (選手の姓名)
  • player_id (プレーヤーID)
  • year (シーズン)
  • ab (打数)
  • hit (安打)
  • single (単打)
  • double (二塁打)
  • triple (三塁打)
  • home_run (本塁打)
  • on_base_percent (出塁率)

 レイアウト名は「player_batting_basic」とします。

スクリーンショット 2025-02-07 23.51.52.png

Login 〜 Log out のテンプレート

 ログインとログアウトはリクエスト毎に行う処理なので、クラスか関数にしておくのがいいでしょう。ここでは、簡単にクラスにして、以後、利用していくことにします。

filemaker-data-api.php

<?php

class FileMaker_Data_API
{
    public $host, $version, $database, $username, $password, $layout;
    public $bearer_session_token;

    function __construct (string $host, string $version)
    {
        $this->host     = $host;
        $this->version  = $version;
    }

    /**
     * リクエスト
     **/

    // ログイン
    public function login (string $database, string $username, string $password): string
    {
		$this->database	= $database;
		$this->username = $username;
		$this->password = $password;

		$auth_value         = $username . ':' . $password;
		$authorization      = 'Authorization: Basic ' . base64_encode($auth_value);
		$content_type       = 'Content-Type: application/json';
		$curlopt_httpheader = array($authorization, $content_type);

		$endpoint        	= "https://{$this->host}/fmi/data/{$this->version}/databases/{$database}/sessions";
		
		return self::executeCurl($endpoint, 'POST', $curlopt_httpheader);
	}

    // ログアウト
    public function logOut(string $database, string $bearer_session_token): string
    {
		$endpoint    = "https://{$this->host}/fmi/data/{$this->version}/databases/{$database}/sessions/{$bearer_session_token}";

		return self::executeCurl($endpoint, 'DELETE');
	}

    /**
     * ユーティリティ
     **/

    // レスポンスコードの取得
	public function getMessagesCode (string $response): string
    {
		$response_array = self::json2array($response);
		return $response_array['messages'][0]['code'];
	}

    // Bearer Session Token 取得
    public function getBearerSessionToken (string $response): string
    {
		$response_array = self::json2array($response);
		$this->bearer_session_token = $response_array['response']['token'];

		return $this->bearer_session_token;
	}

    // JSON を 配列へ変換
	public function json2array (string $json): array
    {
		$json   = mb_convert_encoding($json, 'UTF8', 'ASCII,JIS,UTF-8,EUC-JP,SJIS-WIN');
		return json_decode($json, true);
	}

    // cURL 実行
    static function executeCurl(string $curlopt_url, string $curlopt_customrequest, array $curlopt_httpheader = []): string
    {
		$curl   = curl_init();

		curl_setopt_array($curl, array(
			CURLOPT_URL => $curlopt_url,
			CURLOPT_RETURNTRANSFER => true,
			CURLOPT_ENCODING => '',
			CURLOPT_MAXREDIRS => 10,
			CURLOPT_TIMEOUT => 0,
			CURLOPT_FOLLOWLOCATION => true,
			CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
			CURLOPT_CUSTOMREQUEST => $curlopt_customrequest,
			CURLOPT_POSTFIELDS => "{}",
			CURLOPT_HTTPHEADER => $curlopt_httpheader,
		));

		$response   = curl_exec($curl);

		curl_close($curl);
		return $response;
	}
}


 やや冗長ですが、処理の流れを分かりやすく書いてみました。これを読み込んで、ログインからログアウトまでのテンプレートを書いてみます。

login-log_out.php

<?php

require_once(__DIR__ . '/filemaker-data-api.php');

$host                   = '(FileMaker Server のドメイン名)';
$version                = 'vLatest';
$database               = '(FileMaker ソリューション名)';
$username               = '(FileMaker ユーザ名)';
$password               = '(FileMaker パスワード)';
$layout                 = 'player_batting_basic';
$bearer_session_token   = null;

$fmda   = new FileMaker_Data_API($host, $version);

// ログイン
$response = $fmda->login($database, $username, $password);

// ログイン成功?
if ($fmda->getMessagesCode($response) === '0') {
    // ログイン成功なら、Bearer Session Token を取得する
    $bearer_session_token   = $fmda->getBearerSessionToken($response);
    echo $bearer_session_token, PHP_EOL;
} else {
    // ログイン失敗の処理を書く
    echo "FileMaker Data API へのログインに失敗しました。\n";
}

// (何らかの処理があり、リンクでページ遷移した想定)

// セッションの検証

// レコード取得

// (何らかの処理)

// ログアウト

$response = $fmda->logOut($database, $bearer_session_token);

 簡単に説明します。

  1. $fmda = new FileMaker_Data_API($host, $version);でクラスのインスタンスを作成します。引数は、FileMaker以後は、$fmdaがハンドルになります
  2. login()メソッドを呼びます
  3. response.messages[0].codeのレスポンスコードを取得します。これが 0 ならログイン成功です
  4. 成功の場合は、getBearerSessionToken() を呼んで、Bearer Session Token を取得します
  5. 失敗の場合は、失敗処理をします
  6. (何らかの処理があり、リンクでページ遷移した想定)
  7. セッションの検証
  8. レコード取得
  9. (何らかの処理)
  10. logOut()メソッドを呼んで、ログアウトします

 尚、コーディングにおけるブレース{}は、クラス、メソッド、関数の場合は改行を入れて、if等その他の場合は、改行しないで書いています。

 以上が、FileMaker Data API の基本的な流れになります。

Validate Session

 Web アプリケーションで、ユーザにログイン情報を入力してもらったら、それを何らかの方法で保持しながら、FileMaker Data API のログイン〜処理〜ログアウトを繰り返すことになりますが、ログイン以降のリクエストは、すべて Bearer Session Token を使って行います。

しかし、Web 閲覧中のユーザの行動は予測できませんので(例えば、戻る動作をしている、長時間放置している等)、何らかのリクエストをする前には、auth - Validate Session を使って、Bearer Session Token が有効であるのかを検証しましょう。

filemaker-data-api.php への追加コード

(logOut メソッドのブロックの下に追加)
    // データベースセッションの検証
	public function validateSession (string $session_token): string
    {
		$authorization      = 'Authorization: Bearer ' . $session_token;
		$curlopt_httpheader = array($authorization);
		$endpoint        	= "https://{$this->host}/fmi/data/{$this->version}/validateSession";

		return self::executeCurl($endpoint, 'GET', $curlopt_httpheader);
	}

login-log_out.php// セッションの検証// レコード取得のコメントの部分を書き換えます。

// セッションの検証
$response   = $fmda->validateSession($bearer_session_token);
if ($fmda->getMessagesCode($response) === '0') {
    // セッション有効なら、行いたいリクエスト実行
    echo "成功\n";
    // レコード取得
} else {
    // セッション無効なら、必要な Web データを保持して、ユーザに再ログインを促す
    echo "再ログインしてください。\n";
}

Get Records

 セッションを検証したら、メインのリクエストを行います。

 まず、クラスに、records - Get Recordsのメソッドを追加します。

(validateSession メソッドのブロックの下に追加)
    // レコード範囲の取得
	public function getRecords(string $database, string $layout, string $bearer_session_token): string
    {
		$this->layout		= $layout;

		$authorization      = 'Authorization: Bearer ' . $bearer_session_token;
		$curlopt_httpheader = array($authorization);
		$endPoint        	= "https://{$this->host}/fmi/data/{$this->version}/databases/{$database}/layouts/{$layout}/records";

		return self::executeCurl($endPoint, 'GET', $curlopt_httpheader);
	}

 先程書き換えたセッションの検証のブロックの if の中身を書き換えます。

// セッションの検証
$response   = $fmda->validateSession($bearer_session_token);
if ($fmda->getMessagesCode($response) === '0') {
    // セッション有効なら、行いたいリクエスト実行
    $response   = $fmda->getRecords($database, $layout, $bearer_session_token);
    print_r($response);
    // レコード取得
} else {
    // セッション無効なら、必要な Web データを保持して、ユーザに再ログインを促す
    echo "再ログインしてください。\n";
}

 成功すると、何やら JSON の塊が表示されますが、一応、Get Records が出来ました。
 しかし、Get Records リクエストには、様々なパラメータを渡せます。また、取得できたのは、1,375件中 Get Records のデフォルトの100件のみです。

次回は、レスポンスの JSON の構造と Get Records のもう少し、細かい使い方をやってみたいと思います。

完成版 filemaker-data-api.php

<?php

class FileMaker_Data_API
{
    public $host, $version, $database, $username, $password, $layout;
    public $bearer_session_token;

    function __construct (string $host, string $version)
    {
        $this->host     = $host;
        $this->version  = $version;
    }

    /**
     * リクエスト
     **/

    // ログイン
    public function login (string $database, string $username, string $password): string
    {
		$this->database	= $database;
		$this->username = $username;
		$this->password = $password;

		$auth_value         = $username . ':' . $password;
		$authorization      = 'Authorization: Basic ' . base64_encode($auth_value);
		$content_type       = 'Content-Type: application/json';
		$curlopt_httpheader = array($authorization, $content_type);

		$endpoint        	= "https://{$this->host}/fmi/data/{$this->version}/databases/{$database}/sessions";
		
		return self::executeCurl($endpoint, 'POST', $curlopt_httpheader);
	}

    // ログアウト
    public function logOut(string $database, string $bearer_session_token): string
    {
		$endpoint    = "https://{$this->host}/fmi/data/{$this->version}/databases/{$database}/sessions/{$bearer_session_token}";

		return self::executeCurl($endpoint, 'DELETE');
	}

    // データベースセッションの検証
	public function validateSession (string $session_token): string
    {
		$authorization      = 'Authorization: Bearer ' . $session_token;
		$curlopt_httpheader = array($authorization);
		$endpoint        	= "https://{$this->host}/fmi/data/{$this->version}/validateSession";

		return self::executeCurl($endpoint, 'GET', $curlopt_httpheader);
	}

    // レコード範囲の取得
	public function getRecords(string $database, string $layout, string $bearer_session_token): string
    {
		$this->layout		= $layout;

		$authorization      = 'Authorization: Bearer ' . $bearer_session_token;
		$curlopt_httpheader = array($authorization);
		$endPoint        	= "https://{$this->host}/fmi/data/{$this->version}/databases/{$database}/layouts/{$layout}/records";

		return self::executeCurl($endPoint, 'GET', $curlopt_httpheader);
	}

    /**
     * ユーティリティ
     **/

    // レスポンスコードの取得
	public function getMessagesCode (string $response): string
    {
		$response_array = self::json2array($response);
		return $response_array['messages'][0]['code'];
	}

    // Bearer Session Token 取得
    public function getBearerSessionToken (string $response): string
    {
		$response_array = self::json2array($response);
		$this->bearer_session_token = $response_array['response']['token'];

		return $this->bearer_session_token;
	}

    // JSON を 配列へ変換
	public function json2array (string $json): array
    {
		$json   = mb_convert_encoding($json, 'UTF8', 'ASCII,JIS,UTF-8,EUC-JP,SJIS-WIN');
		return json_decode($json, true);
	}

    // cURL 実行
    static function executeCurl(string $curlopt_url, string $curlopt_customrequest, array $curlopt_httpheader = []): string
    {
		$curl   = curl_init();

		curl_setopt_array($curl, array(
			CURLOPT_URL => $curlopt_url,
			CURLOPT_RETURNTRANSFER => true,
			CURLOPT_ENCODING => '',
			CURLOPT_MAXREDIRS => 10,
			CURLOPT_TIMEOUT => 0,
			CURLOPT_FOLLOWLOCATION => true,
			CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
			CURLOPT_CUSTOMREQUEST => $curlopt_customrequest,
			CURLOPT_POSTFIELDS => "{}",
			CURLOPT_HTTPHEADER => $curlopt_httpheader,
		));

		$response   = curl_exec($curl);

		curl_close($curl);
		return $response;
	}
}

完成版 get_records.php

<?php

require_once(__DIR__ . '/filemaker-data-api.php');

$host                   = '(FileMaker Server のドメイン名)';
$version                = 'vLatest';
$database               = '(FileMaker ソリューション名)';
$username               = '(FileMaker ユーザ名)';
$password               = '(FileMaker パスワード)';
$layout                 = 'player_batting_basic';
$bearer_session_token   = null;

$fmda   = new FileMaker_Data_API($host, $version);

// ログイン
$response = $fmda->login($database, $username, $password);

// ログイン成功?
if ($fmda->getMessagesCode($response) === '0') {
    // ログイン成功なら、Bearer Session Token を取得する
    $bearer_session_token   = $fmda->getBearerSessionToken($response);
    echo $bearer_session_token, PHP_EOL;
} else {
    // ログイン失敗の処理を書く
    echo "FileMaker Data API へのログインに失敗しました。\n";
}

// (何らかの処理があり、リンクでページ遷移した想定)

// セッションの検証
$response   = $fmda->validateSession($bearer_session_token);
if ($fmda->getMessagesCode($response) === '0') {
    // セッション有効なら、行いたいリクエスト実行
    $response   = $fmda->getRecords($database, $layout, $bearer_session_token);
    print_r($response);
    // レコード取得
} else {
    // セッション無効なら、必要な Web データを保持して、ユーザに再ログインを促す
    echo "再ログインしてください。\n";
}

// レコード取得

// (何らかの処理)

// ログアウト

$response = $fmda->logOut($database, $bearer_session_token);

login-log_out.php テンプレート

<?php

require_once(__DIR__ . '/filemaker-data-api.php');

$host                   = 'remixworks.cloud';
$version                = 'vLatest';
$database               = 'remixworks_test';
$username               = 'remixworks_1228';
$password               = 'tomikf19';
$layout                 = 'player_batting_basic';
$bearer_session_token   = null;

$fmda   = new FileMaker_Data_API($host, $version);

// 次のメタデータ取得のリクエストはログインする必要がない。
// Product Info
// Database Names

/**
 * Login begin
 */
// ログイン
$response = $fmda->login($database, $username, $password);

// ログイン成功?
if ($fmda->getMessagesCode($response) === '0') {
    // ログイン成功なら、Bearer Session Token を取得する
    $bearer_session_token   = $fmda->getBearerSessionToken($response);
} else {
    // ログイン失敗の処理を書く
    echo "FileMaker Data API へのログインに失敗しました。\n";
}
/**
 * Login end
 */

// (何らかの処理があり、リンクでページ遷移した想定)

// セッションの検証
$response   = $fmda->validateSession($bearer_session_token);
if ($fmda->getMessagesCode($response) === '0') {
    // セッション有効なら、以下の任意のリクエストを実行
    // 取得 Get Records
    // 取得 Get Single Record by Id
    // 作成 Create Record
    // 編集 Edit Record
    // 編集 Upload to Container Field
    // 編集 Upload to Container Field (specific repetition)
    // 編集 Set Global Fields
    // 削除 Delete Record
    // 複製 Duplicate Record
    // 検索 Find Record
    // スクリプト Execute Script
    // メタデータ取得 Layout Names
    // メタデータ取得 Script Names
    // メタデータ取得 Layout Metadata
    // メタデータ取得 Old Layout Metadata
} else {
    // セッション無効なら、必要な Web データを保持して、ユーザに再ログインを促す
    echo "再ログインしてください。\n";
}

// レコード取得

// (何らかの処理)

/**
 * Log out begin
 */
// ログアウト

$response = $fmda->logOut($database, $bearer_session_token);
/**
 * Log out end
 */

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?