FileMaker

FileMaker Data API チュートリアル5・スクリプト

  • このエントリーをはてなブックマークに追加

※注意
本記事は、Ver17時点の記事であり、最新バージョンの内容とは異なります。
Ver18より、スクリプトを単独実行できるAPIが実装されました。
詳しくは、APIのヘルプ(英語)をご確認ください。
https://fmsdev01.rsc-developer.net/fmi/data/apidoc/#operation/executeScript

こんにちは。
ライジングサン・システムコンサルティングの岩佐です。

この記事では、FileMaker Data API におけるスクリプトの実行方法について解説していきます。この記事で学習を進めるには、このFileMaker Data API シリーズの1・2・3、及び4の内容を理解している必要があります。もしまだそちらの記事をご覧いただいていない方は、こちらの記事から学習をスタートされると、スムーズに進められると思います。

また、今回の学習でもPostmanを利用します。これまでの記事で、Postmanに token 環境変数の自動更新を設定していますので、そちらも確実にできるようにしておいてください。

そして、前の記事でご案内しているサンプルソリューションも、この先実際に手を動かして学習を進めていく上で必要となります。ぜひダウンロードし、ご自身の管理下にある FileMaker Server にホストしておいてください。

1. 標準のスクリプト実行機能だけでは解決できない問題

FileMaker Data API では、スクリプト実行のみを行うAPIは存在せず、必ずレコードの追加・修正・削除、そして検索APIに合わせて実行することになります。

ここで改めて、各 API メソッドで実行可能なスクリプトのタイミングについて確認したいと思います。

パラメータ Create Delete Edit Find 実行タイミング
script.prerequest / script.prerequest.param API実行前
script.presort / script.presort.param API実行後かつソート実行前
script / script.param  APIとソートが実行された後

上記の通り、スクリプトを実行できるタイミングは大きく3つ用意されています。そして、そのタイミング毎に、任意のスクリプトとスクリプト引数を設定できる仕様になっています。

また、上記の表にはGet Record(s)でのスクリプト実行は割愛しています。というのも、Get Record(s)のAPIでもスクリプトの実行は可能ですが、URL内部にスクリプト名やスクリプトパラメータを埋め込むことになるため、現実的にはあまり利用する機会はないと思われるからです。

1-1. 複数レコードを一括更新や追加、削除などができない問題

このように、FileMaker Data API では、必ずレコードの新規追加・修正・削除、及び検索メソッドに合わせてスクリプトを実行する必要があります。しかし、これだけではどうしても実現できない機能要求が発生することも当然出てきます。

例えば、レコードの新規追加・修正・削除に関しては、レコードの処理単位が1件づつになります。ですので、API経由で複数のレコードをまとめて登録したい場合は、そのレコード件数分APIをコールするしかありません。

しかし、この方法はクライアント側、サーバ側ともに様々なオーバーヘッドが発生しそうな処理で、プログラマとしてはあまり採用したくはありません。

1-2. 親子関係のあるレコードのトランザクション処理が実現でいない問題

また、今回のサンプルソリューションには簡易的なPOSデータを仕込んでいますが、このような「売上伝票」形式のテーブル設計は一般的に、Header / Detail のデータモデルが採用されます。つまり、売上伝票ヘッダレコードと売上伝票明細レコードが同時に存在して初めて整合性のあるデータとなるため、一般的にはトランザクション処理が必要になります。

このような場合、レコードを1件づつ処理する仕様になっている FileMaker Data API の標準機能のみだとどうしても限界が出てきます。

しかし、簡単な工夫を施すことで、この限界を超えて複雑な機能をAPIとして実装、公開することも可能です。それでは、実際に簡単な機能要求を仮定して、その方法について考察してみたいと思います。

2. 複数レコードの更新処理を実装する

まずは複数のプロダクトアイテムに対して、一括して取扱中止日を設定するという機能要求を仮定してみたいと思います。

この場合、FileMaker Data API の標準機能では、まず処理対象レコードのレコードIDを取得し、そのレコードIDをURLに指定して、必要な数だけ Edit Record API を実行することになります。これは処理対象のレコード件数が少なければ良いのですが、まとまった数を一気に処理したい場合は、非常にコストの高い処理を実装する必要があります。

ですので今回は、この処理を1回の API コールのみで実現できる方法を考えてみましょう。

2-1. 処理負荷がほぼゼロの検索と組み合わせる

先述のとおり、FileMaker Data API では、どうしても用意されている API メソッドに合わせてスクリプトを実行する必要があるので、処理負荷ができるだけ小さな API を組み合わせて任意のスクリプトを実行できると良いのではないかと思います。

そこで、実行したいスクリプトが格納されている fmp12 ファイルに、レコード件数が常に1件しか存在しないテーブルを用意し、そのテーブルへのfindメソッドに合わせて、任意のスクリプトを実行できれば、 API の処理自体は極めてゼロに近い負荷で、任意のスクリプトを実行できるのではないかと考えました。

そこで今回は、サンプルソリューションの中に global というグローバルフィールドのみで構成され、レコード件数が常に1件のテーブルを用意し、そのテーブルへの検索を実行すると同時に、スクリプトを実行するというサンプル機能を実装してみたいと思います。

2-2. 仮の機能要求:JSON配列で指定したJANコードをもつアイテムの中止日を一括更新

まずはプロダクトアイテムテーブルに登録されている複数のレコードに対して、同一の中止日を設定するというシナリオでサンプル機能を実装してみます。

まずスクリプトにわたす引数を考えてみます。引数はJSONフォーマットで渡すことがWebAPIの慣例かと思いますので、次のような引数で渡したいと思います。

{
        "end_date" : "2018/12/31",
        "jan_code" : 
        [
                "4900000000001",
                "4900000000002",
                "4900000000003",
                "4900000000004",
                "4900000000005"
        ]
}

end_date はセットする終了日。 jan_code はJSON配列担っており、その中に任意の数のJANコードを設定すると、それらの取り扱い終了日が一括設定されるというシナリオです。

次にスクリプトですが、今回の記事はFileMakerのスクリプトに関するテクニックをご紹介するものではありませんので、サンプルソリューションをダウンロードいただき、完全アクセス権でファイルを開いてご確認ください。引数の妥当性チェックや、適切なエラーハンドリングも一切実装していない、極めて簡易的なスクリプトが実装されています。

2-3. Postmanから終了日の一括更新スクリプトを実行

それでは実際にPostmanを操作して、スクリプトを実行してみましょう。APIのリクエストボディには、以下のJSONパラメータを設定してください。

またターゲットになるレイアウトは、 T00_GLOBAL という常にレコードが1件のみ登録さてている、グローバルフィールドのみで構成されたテーブルです。

{
 "query":[{"_true_": 1 }],
 "script" : "setEndDate",
 "script.param" : "{\"end_date\":\"2018/12/31\",\"jan_code\":[\"4901170017330\",\"4901170018436\",\"4901170017453\",\"4901170017590\",\"4901170017514\"]}"
}

queryパラメータは、trueというフィールドが1の値を検索する指定になっています。これは1レコードしか存在しなく、かつ常に1という値を持っているフィールドなので、検索負荷はほぼゼロといって良いと思います。

2-4. 動画で実際の動きを確認

それでは、スクリプトを実行する様子を動画で確認してみましょう。

3. 親子関係のあるレコードを登録する

次に、親子関係のあるレコードを一回のスクリプトで登録してみましょう。今回のサンプルソリューションで親子関係を持っているテーブルは、メーカーとプロダクトアイテム。そして売上伝票ヘッダテーブルと、売上伝票明細テーブルがあります。

一般的に、メーカーとプロダクトアイテムの関係性は、1:0〜nになると思いますが、売上伝票ヘッダテーブルと売上伝票明細テーブルの関係性は、1:1〜nになります。

FileMaker Data API の標準機能のみでこれを処理するとなると…

1.売上伝票ヘッダテーブルにヘッダレコードを1件登録
2.レコードの新規追加APIのレスポンスにから、新規追加したレコードIDを取得。
3.取得したレコードIDを元に、Get Record メソッドを実行して、新規追加したレコードのプライマリキー値を取得。
4.取得した売上伝票ヘッダテーブルのプライマリキー値を外部キー値として、売上伝票明細テーブルにレコードを必要件数分登録

…と、非常にコストの高い処理を実装しなければなりません。

しかも、ヘッダレコードと明細レコードの登録を実行するリクエストが別れてしまうので、一時的にせよヘッダと明細の関係性が 1:0 の状況が発生し、あまり好ましい状態とは言えません。

3-1. 親子関係のあるデータを一括処理する引数を設定

そこで今回は、売上伝票ヘッダテーブルと明細テーブルに、1回のリクエストで処理するための引数を考えてみましょう。一般的にはこのような引数になると思います。

{
   "storeCode":1003,
   "date":"2018/12/10",
   "time":"12:00:00",
   "sell_item":[
      {
         "jan_code":"4901861099898",
         "quantity":5
      },
      {
         "jan_code":"4901861095012",
         "quantity":5
      },
      {
         "jan_code":"4901861039726",
         "quantity":5
      },
      {
         "jan_code":"4901861039702",
         "quantity":5
      },
      {
         "jan_code":"4901861021912",
         "quantity":5
      }
   ]
}

このJSONを見るだけでも、ストアコード 1003 で、2018年12月10日の12時00分に、5品目の商品が5点づつ売れたことが目視で想像がつくと思います。APIの引数は、このように「何を処理しようとしているのか」を、引数を見るだけでさっと確認できることがとても重要です。

3-2. 複雑なスクリプト引数は、Base64で渡す

前のスクリプト引数と比較すると、今回のスクリプト引数はJSON配列の中に、更にJSONオブジェクトがあるような複雑な構造を持っています。恐らく実際のソリューションを構築する場面では、もっと複雑なJSONを渡す必要も出てくるでしょう。

FileMaker Data API では、JSON形式のリクエストボディに、JSON形式のスクリプト引数を埋め込む必要があるので、ダブルクオーテーションや改行コードなど、特定の文字列はバックスラッシュでエスケープする必要があります。

このエスケープはなかなか面倒で、何が特殊文字かを予めプログラマが把握しておく必要がありますし、思わぬバグが内在してしまう可能性もあります。

このような複雑な構造のJSONデータを渡す場合は、Base64でエンコードしてしまうと、APIをコールする方もされる方も非常に楽です。ですので今回の引数は、Base64でエンコードして渡すことにしましょう。

こちらが、PostmanからBase64でエンコードされたJSONデータをスクリプト引数として渡している様子です。

3-3. 動画で実際の動きを確認

それでは実際の動きを動画で確認してみましょう。

4. まとめ

この記事では、FileMaker Data API の標準機能のみでは実装が困難な複雑な機能要求を、スクリプトで実装する方法について解説してきました。

恐らくここで紹介した以外にも様々な方法があると思いますし、ある観点から見ると今回ご紹介した方法はあまり好ましい実装方法ではないかもしれません。

4-1. セキュリティに関する考慮

また、今回お配りしているサンプルソリューションでは、引数のバリデーションや、SQLデータベースで言うところのSQLインジェクションに該当するような、不正な処理が実行されてしまう可能性のある引数を無効とするような処理は実装していません。

APIを公開するということは、FileMakerプラットフォームとは全く無縁の方であったり、公開の範囲によっては悪意のあるクラッカーから攻撃を仕掛けられるケースも考えられます。

このような背景から、引数を設定させてのAPIを介したスクリプト実行には、十分な考慮とテストが必要になります。

4-2. 大きなエコシステムの一部としてのFileMakerプラットフォームの可能性

FileMakerプラットフォームで開発したソリューションは、これまではどうしても他システムと結合するためにODBC接続などによる「密結合」でしか実現ができませんでした。

しかし FileMaker Data API が正式リリースされたことで、企業内における様々なシステムと、相互に「疎結合」できる事になりました。

各システム間を疎結合で結んで、緩やかなエコシステムを構築することは、現在の非常に大きなトレンドのひとつです。

そして、FileMakerプラットフォームもそのトレンドに対応できたことで、より広域にFileMakerに蓄積されたデータやビジネスロジックを利活用することができるようになりました。

ご存知の通り、FileMakerプラットフォームは、ある意味得意な分野と不得意な分野がはっきりと別れている開発プラットフォームです。ですので、FileMakerが不得意な部分は、思い切って他の開発プラットフォームで実装し、FileMakerプラットフォームは、自らの強みが活かせる部分にフォーカスするような考え方が、今後ますます重要になってくると思います。

その強みにフォーカスするためにも、他の開発プラットフォームとの境界線となるFileMaker Data APIの使い方は必ずマスターしておきたいものです。

ぜひこれを機に、実際に自分で手を動かしてFileMaker Data API の世界を堪能し、新たな可能性に対して思いを馳せてみてください。

  • このエントリーをはてなブックマークに追加