A NodeJS wrapper for interfacing with the Claris FileMaker Data API.
npm install fm-dapifm-dapi
===========
The fm-dapi packages provides a DapiClient object which is a TypeScript class that provides an easy-to-use interface for interacting with FileMaker's Data API. The class allows you to perform common CRUD (create, read, update, delete) operations on FileMaker records, as well as execute find requests and perform scripts.
With DapiClient, you can connect to your FileMaker database and authenticate with the Data API using your account credentials. Once authenticated, you can use the class methods to interact with your data, passing in data in the form of TypeScript objects and receiving data back in the same format.
DapiClient is designed to be simple and easy to use, with a clear and concise API that abstracts away the complexity of working with the Data API directly. It also provides error handling and logging to help you troubleshoot issues when they arise.
Installation
===========
Using npm:
``bash`
$ npm install fm-dapi
Using yarn:
`bash`
$ yarn add fm-dapi
Usage
===========
DapiClient Configuration
----------------------
To use the fm-dapi, initialize the DapiClient with the credentials for your FileMaker host and database.
The client automatically handles creating sessions and maintaining session tokens. When the first request is made, a session will be created and the token will be stored. This token will be reused for as long as the session is active. Once the session expires, a new session token will be regenerated.
`JavaScript
import {DapiClient} from 'fm-dapi' // or const {DapiClient} = require('fm-dapi')
// Set configuration
const dapiClient = new DapiClient({
username: process.env.USERNAME,
password: process.env.PASSWORD,
version: "vLatest",
host: "mydomain.com",
database: "databaseName"
});
`
Additional Configurations
----------------------
There are some optional arguments that are available to use.
This system is useful if you have multiple apps accessing the same database and you want them all to use the same session. In this case, you can store the session token in a Redis DB and have the 'getSharedToken' read from that DB and the 'updateSharedToken' update the value in the DB.
`JavaScript`
// Set configuration
const dapiClient = new DapiClient({
username: process.env.USERNAME,
password: process.env.PASSWORD,
version: "vLatest",
host: "mydomain.com",
database: "databaseName"
maxAttempts: 3, // Optional. Defaults to 1.
getSharedToken: async function() {
// get token from DB...
return token;
}, // Optional
updateSharedToken: async function(sessionToken) {
// update token in DB with sessionToken...
} // Optional
});
Working with records
----------------------
`JavaScript
const layout = "People_Create"
const hanSolo = {
"name": "Han Solo",
"gender": "male",
"height": "180",
"mass": "80",
"hair_color": "brown",
"skin_color": "fair",
"eye_color": "brown",
"birth_year": "29BBY"
}
const fmRequest = {
"fieldData": hanSolo
}
const fmResponse = await dapiClient.createRecord(layout, fmRequest)
`
JavaScript
const layout = "People"
const recordId = 101const fmResponseSingleRecord = await dapiClient.getRecord(layout, recordId)
const fmResponseRangeOfRecords = await dapiClient.getRecords(layout) // returns the first 100 records
`$3
To update a record, pass in the layout name, recordId, and an object with the field data you would like to update.
`JavaScript
const layout = "People_Edit"
const recordId = 1const lukeRecord = {
"rank": "Jedi Knight",
"lightsaber": 'green'
}
const fmRequest = {
"fieldData": lukeRecord
}
const editResponse = await dapiClient.editRecord(layout, recordId, fmRequest)
`$3
To delete a record, pass in the layout name and recordId of the record you want to delete.
`JavaScript
const layout = "People"
const darthVaderRecordId = 2const deleteResponse = await dapiClient.deleteRecord(layout, darthVaderRecordId)
`Performing find requests
----------------------
You can use the 'createFindRequest' method to easily build out and perform a find request. It provides different connector functions for different comparison operators and allows you to chain find requests by using the 'and' function. It also supports all of the normal options inside of the 'createFindRequest' method. The find won't be performed until you call the 'perform' method on it.
Here is a site of all the comparison functions.
- is(value) // loose find
- isEqualTo(value) // strict find
- isLessThan(value)
- isLessThanOrEqualTo(value)
- isGreaterThan(value)
- isGreaterThanOrEqualTo(value)
- isEmpty()
- isBetween(startValue, endValue) // search using startValue...endValue
$3
`JavaScript
const layout = 'Planets'const sort = [
{
"fieldName": "size",
"sortOrder": "descend"
}
]
const rebelBaseLocations = await dapiClient.createFindRequest({
sort: sort, // optional
portals: [ "Rebel Leaders" ] // optional
})
.where('population').isLessThan(2000).and('remoteness').is('extreme')
.where('allegiance').isEqualTo('Rebellion')
.omitWhere('already_searched').isEqualTo(1)
.perform()
`$3
You can also manually build out the query object and pass it with all of the normal options into the performFind method.`JavaScript
const layout = ''const query = [
{
"population": 2000,
"remoteness": "extreme"
},
{
"allegiance": "Rebellion"
},
{
"already_searched": 1,
"omit": "true"
}
]
const sort = [
{
"fieldName": "size",
"sortOrder": "descend"
}
]
const findResult = await dapiClient.performFind(layout, {
query: query,
sort: sort, // optional
portals: [ "Rebel Leaders" ] // optional
})
`Running FileMaker Scripts
----------------------
To perform a FileMaker script, pass in the layout name, script name, and script parameter.
Please note that this method use a GET request and passes the script parameter as a URL parameter. This means that the script parameter is bound by the URL parameter character limit which can cause issues if you are trying to pass very large JSON or Base64Encoded script parameters. In this case, it would be better to run the script by including it in the request body of either a find request or a create/edit request (see https://help.claris.com/en/data-api-guide/content/run-script-with-another-request.html)
`JavaScript
const layout = 'Space'
const script = 'Destroy Death Star'
const parameter = 'Torpedo'const scriptResponse = await dapiClient.performScript(layout, script, parameter)
`Getting metadata
----------------------
Not implemented
Upload container data
----------------------
Not implemented
Setting global fields
----------------------
Not implemented
Miscellaneous functions
----------------------
`JavaScript
dapiClient.getHost() // returns host that the DapiClient is assigned to connect todapiClient.getVersion() // returns dapi version that the DapiClient is assigned to use
dapiClient.getDatabase() // returns host that the DapiClient is assigned to connect to
dapiClient.getBaseUrl() // returns baseUrl with the format
https://${host}/fmi/data/${version}/databases/${database}await dapiClient.getSessionToken() // returns the session token currently in use
``This project is licensed under the MIT License - see the LICENSE file for details