Learning the FileMaker Data API by trial and error.
I’ve recently completed work on integrating the FileMaker Data API into a Javascript application. I fumbled around during the process and wanted to document my thoughts while my impressions were still fresh.
The most significant issue: finding the correct documentation
I’ll start with the conclusion. My searches didn’t surface the correct documentation when I began the process, so I’ll share some URLs to begin.
- The Claris FileMaker Data API documentation: https://help.claris.com/en/data-api-guide/content/index.html
- FileMaker 18 Data API Guide (specifically, the section labeled “Write FileMaker Data API calls”): https://fmhelp.filemaker.com/docs/18/en/dataapi/
- Claris OData API and FileMaker OData API Guide: https://help.claris.com/en/odata-guide/content/write-odata-api-calls.html
- FileMaker Data API v1 Postman Collection: https://github.com/johnfmorton/filemaker-dataapi-collection-for-postman
- FMDataAPI, a class developed in PHP to access the FileMaker database with Claris FileMaker Data API: https://github.com/msyk/FMDataAPI
My Google fu rarely fails me. I can find just about anything when I set my mind to it. Perhaps I was off my game during the early phases of this project, but I suspect the naming conventions for the Claris products have something to do with the poor quality of my search results.
The FileMaker documentation link references many similarly named products: Claris Studio, “Claris Pro and FileMaker Pro,” “Claris Server and FileMaker Server,” Claris Connect, FileMaker Pro, FileMaker Pro Advanced, FileMaker Cloud, FileMaker Cloud for AWS, and FileMaker Server, all with version numbers. That not only confused me, but posts by users around the internet often speak of FileMaker generically, but it could be any one or all of these products.
My discovery development process
I ran into multiple problems as I worked on my project, but I was able to cobble together solutions that worked through trial and error. You have the links above, but my path through the API has given me a decent understanding of what is happening. It just took more time than I wanted.
If you’re reading this, you might run into similar problems, and I hope my experience can help you get through these issues quicker. The main things I’ll touch on here are:
- Use Postman to quickly test your API calls
- Use a proxy to deal with CORS issues when accessing the FileMaker Data API
- Accessing files, PDFs in my case, from a FileMaker container
I’m not a FileMaker developer
If you’re a FileMaker developer, you may marvel at my lack of understanding of FileMaker. I came into this project just wanting to query an API endpoint. I worked with a FileMaker developer who created all of the endpoints for me in FileMaker. He created the layouts and exposed data in the layouts for me to query. Later in this post, I mention the Users_Api. I think this is a custom layout created in FileMaker, not something built by default in FileMaker. If you’re looking for information on how to do that, I won’t cover that here.
Starting with Postman
I started my discovery using Postman. I found a collection of FileMaker Data API calls that I imported into Postman. The collection was extremely helpful, but unfortunately, I didn’t document where this collection came from. I have exported the Postman collection, which includes some additions I made, and posted it to a GitHub repo, FileMaker Data API v1 Postman Collection. I wish I could thank the original poster. Thank you, anonymous internet person.
This collection allowed me to start making requests to FileMaker in a repeatable way.
As shown in the screenshot above, the authentication request is the first item in the FileMaker Data API collection, and that’s where I started. The URL, https://{{server}}/fmi/data/v1/databases/{{database}}/sessions, includes variables in curly brackets. I had two different users set up for my tests, a user with full access and a user with limited access. I set up Environmental variables for each user. Read about using Postman variables in the documentation.
The collection allowed me to test whether the FileMaker server was responding to my log-in attempt and allowed me to see what sort of data I could expect back. When I saw that a bearer token was being returned, that opened up the rest of the API to me.
Now that logging into FileMaker worked, I wrote the rest of the API calls I needed to make, using the other API calls in the collection as a starting point. For example, I needed to query for all users (when in a “super admin” session), get the details of a user account (when in a limited-access session), get a list of records for a single user, run a FileMaker script, and more.
For example, the screenshot below is a work-in-progress of debugging a call to retrieve users from a layout called Users_Api.
FileMaker & CORS headers
After the test API calls worked successfully in Postman, I thought my job was nearly finished. I imagined jumping into Javascript development and sailing through to a finished app. I just needed the CORS headers set up on the FileMaker server to allow my app to access the API. This turned out to be a significant stumbling point.
The FileMaker developer I worked with has other FileMaker instances using the FileMaker API successfully, but that communication was server-to-server, not web browser-to-server. That’s when I realized I needed to write a proxy between my web app and the FileMaker endpoint. CORS headers are not an issue when no web browser is in the mix.
PHP as a FileMaker proxy
Since PHP is the server language I’m most comfortable with, that’s where I started. I wrote a custom proxy service that accepted the requests from my Javascript application and then forwarded them to the FileMaker API. Since I had full control over the proxy server, I could set the CORS rules I needed to communicate between a web browser and my proxy.
This worked surprisingly well. And as a little bonus win, I cleaned up the data returned from FileMaker before passing it back to the Javascript app.
If, as you read this, you decide you need to create a PHP proxy, be sure to check out FMDataAPI on GitHub because it might save you a lot of time. I only discovered this project after I had my proxy nearly finished. The reason I discovered FMDataAPI, though, was my last major hurdle.
Displaying PDFs and other files from FileMaker through the API
My PHP FileMaker proxy delivered the textual data to my app as I needed, but one page of my app was a list of links to PDFs. These were monthly statements the users needed to view.
This is the format of the URL that I would receive from FileMaker:
https://example-filemaker-server.com/Streaming_SSL/MainDB/abcdef12345ghijkl6789.pdf?RCType=EmbeddedRCFileProcessor
Linking out to these URLs would not load the PDFs in the web browser. I needed my proxy to intercept these URLs and load the PDF instead. I formatted my request like this:
https://my-proxy-server.com/api/fm-proxy-pdf-viewer.php?token=123token456&pdfUrl=https%3A%2F%2Fexample-filemaker-server.com%2FStreaming_SSL%2FMainDB%abcdef12345ghijkl6789.pdf%3FRCType%3DEmbeddedRCFileProcessor
I’ll break this URL down into pieces.
- The location of my proxy:
https://my-proxy-server.com/api/pdf-viewer.php
- The
token
parameter is used to make requests to FileMaker - The
pdfUrl
parameter is a URL Encoded copy of the PDF URL provided by FileMaker
I’ve posted the script for the FileMaker PDF Proxy I ended up using in a GitHub gist. https://gist.github.com/johnfmorton/507af6c5b649a2afeafc799888420228
This script took a lot of debugging, but the piece that tripped me up the most was the need for a cookie jar, on line 40 in my Gist.
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookieFile); // save cookies
I discovered someone having the same authorization issue with file access that I was experiencing in a thread on GitHub, https://github.com/msyk/FMDataAPI/issues/18, in the FMDataAPI project issues. Not only did this solve my problem, but if I’d discovered this project earlier, it might have negated the need for me to create my PHP proxy. Since my proxy was now complete, I kept it, but if you’re thinking of writing your own, I’d suggest checking out this project first.
One-time use URLs
I once again thought my project was nearly complete. I was so happy with how things were working. My Javascript app connected with only one API but three of them: FileMaker, Craft CMS, and a custom payment gateway. (Connecting to Craft CMS is a breeze, so I didn’t feel the need to write a big post about that.)
I was walking my client through the app, feeling pretty pleased with myself. I logged in and showed him the FileMaker data. It was smooth as butter. I opened a PDF, and it displayed as expected. I clicked around the app some more, showing him the payment portion, and as I was wrapping up, I clicked to open the PDF again, but it failed to open. I closed the PDF window and tried again. No luck again. Only during the client review did I realize the links to the PDF files were good only for a single visit.
Since I had come this far with no real documentation to speak of, I’m not too embarrassed by this, but I wish I had known it earlier.
The solution to this problem was pretty simple, though. When a user clicks the link to open the PDF, I send an additional request to FileMaker to get a new URL for that PDF and silently update it in the file list in the Javascript app. Now, the logged-in user can view the PDFs as much as they want.
Timing out of tokens
One of the final things I worked on in my Javascript app was to manage the token timers. There are 3 timers I manage in my app.
- The Javascript app user sessions log out after 10 minutes of inactivity.
- The FileMaker token will expire after 15 minutes from the last use of the token.
- The FileMaker token will expire after 16 hours, no matter how often it is used.
The FileMaker token timeouts are not something I have found in the documentation. These times were things I discovered through conversations with the FileMaker developer I worked with. I’m just passing it along in case you’re wondering about those times too.
In my Javascript app, I have three countdown timers running at all times and refresh them based on user activity in the app. If the user is active in the app for 14 minutes but has not hit the FileMaker API, I silently make a request to FileMaker to keep the FileMaker token active. If a user uses the app for 16 hours, I log them out, no matter how much they’d like to stay logged in.
End of the brain dump
That’s all I’ve got for you on working with the FileMaker Data API, and I wish you luck in building your app if that’s why you’ve read this far. Cheers.