Library
Integrating an External eCommerce Website
So you provide an eCommerce website and have been tasked with reading product definitions from Fieldpine. This guide walks you through the initial steps.
Before you start, you will need the Fieldpine hostname you are to use, and your APIKey
Lets test that works before we do anything. Issue this query
https://YOUR-HOSTNAME/fd1/debug/ping/HelloWorld?_invalid=6&x-apikey=YOUR-API-KEY
You should receive a valid looking response.
- Placing the ApiKey as a query parameter is not recomended, but works fine while you get going
-
Your ApiKey should normally be sent as a HTTP header when using HTTP mode, or in your session login when using websocket mode.
curl -H "x-apikey: YOUR-API-KEY" https://... - Responses are always in JSON.
- Your ApiKey may be placed in "developer mode" which means the Apis might return additional details to help you. If you ran the query above and saw a "developer_notes" in the response, then developer_mode is enabled.
- Developer Mode is enabled by the administrator, you cannot enable it
- When in developer mode, responses are pretty-printed, but production level responses do not pretty print
Reading Products - Simple HTTP GET
To read products, the simple HTTPS request is
https://YOUR-HOSTNAME/fd1/data?x-apikey=YOUR-API-KEY&_v.table=logical.products[publish=1]&_v.limit=5
- The URL path is /fd1/data which refers to the endpoint fd1.data This is a generic data access endpoint
- The _v.table tells the endpoint which table you want. Fieldpine consider everything to be a "table", it does not necessary mean it is an SQL database table
- The table we want is logical.products[publish=1] which means we want the logical (ie user level view) products list. the [publish=1] tells us we only want products marked publish=1. Consider this like an SQL where clause, but it is slightly different to that. Your ApiKey will probably force publish=1 as well.
- _v.limit=5 This is restricting the output to 5 rows. For practical use you wont have a limit
- Fieldpine APIs typically do not enforce row limits on responses, if you want 37,000 product records, we will send them. It's a bit more complex in reality, PII type data is harder to bulk download, but most retailers don't restrict products
- The response will return a default set of product fields. This will not match what you want. To solve this your request uses "qo" query output
- If you are issuing the above query in curl, you may need the -g switch to disable globbing. The presence of [ ] has meaning to curl
Reading Products - HTTP POST
To really get the most out of the Api, we need to send a JSON packet describing our request. While we can do it all via a GET and query parameters, that gets pretty ugly pretty fast. And a GET is internally converted to a JSON request anyway on the server, so lets save some time.
To send a POST request, we need to use curl or similar type tool. First create a file containing your JSON request. If you are creating an object in Javascript then you may need to change quoting to match those requirements.
File: myRequest.json
{
"a": "fd1.data",
"v": {
"table": "logical.products[publish=1]",
"limit": 5
}
}
That packet is what our original HTTP GET turned into. Lets send it.
curl -H "x-apikey: YOUR-API-KEY" -d @myRequest.json https://YOUR-HOSTNAME/fd1/data
- This is sent as a POST verb. curl does that automatically when we use @d
- For HTTP requests, the query path (/fd1/data) must match the "a" field in the packet. This is a security restriction
To alter the returned fields, change the file myRequest.json to be
{
"a": "fd1.data",
"v": {
"table": "logical.products[publish=1]",
"limit": 5
},
"qo": {
"pid": true,
"description": true,
"their-sku": "plucode",
"_$change_counter": true
}
}
The "qo" query output sets the output JSON structure you want to receive. The doc page has more details, but briefly
- The "pid": true and "desrciption": true mean copy the matching fields
- The "their-sku": "plucode" mean we take in the input field "plucode", and place it in your object called "their-sku"
- This might seem a tad pointless when you just want a list of products, but really kicks in when you get a bit more complex, such as stock levels per physical store
- "_$change_counter" is a Fieldpine internal field, we going to use that shortly.
Until now, we've been fetching all published products. What if we just want a subset? The common request is for a specific department, but for this doc we will search for products with "red" in their name and in department #4. This will probably return no rows against your data, but the syntax is clear.
To do this, we add a "q" query fields object. This is like a list of where clauses in SQL terms, but they are not SQL
Chagne myRequest.json to
{
"a": "fd1.data",
"v": {
"table": "logical.products[publish=1]",
"limit": 5
},
"qo": {
"pid": true,
"description": true,
"their-sku": "plucode",
"_$change_counter": true
},
"q": {
"description(like)": "red",
"department": 4
}
}
And send it
curl -H "x-apikey: YOUR-API-KEY" -d @myRequest.json https://YOUR-HOSTNAME/fd1/data
You should receive something like
{
"r": "fd1.data",
"data": {
"rows": [
{
"pid": 123,
"description": "Red pants",
"their-sku": "RP982",
"_$change_counter": 20260203.223409
}
...
]
}
}
Fetching only Changed Products
Until now we've been fetching all products. But we can optomise things and only request changed products. We do this using "_$change_counter" and a "q object." The logic is
- Request all products initially.
- Process these into your system, remembering the highest _$change_counter you see. _$change_counter is an opaque meaningless string value, but it can be sorted using normal alphanumeric sorting
- Wait for your next poll time, and put a "q", with the _$change_counter from step #2
- A safety measure, periodically repoll everything. You will need to do this, as this "_$change_counter" method does not detect removals, where a product was published, but isn't any more
If the highest _$change_counter we've handled is "20260203.223409|82931", then we can use this to select only changes since that time
{
"a": "fd1.data",
"v": {
"table": "logical.products[publish=1]",
"limit": 5
},
"qo": {
"pid": true,
"description": true,
"their-sku": "plucode",
"_$change_counter": true
},
"q": {
"_$change_counter": "1|20260203.2234093847364|82931"
}
}
- When using a selection (q) with _$change_counter the rows are implicitly in sorted ascending order
- _$change_counter values are unique within a table
- A rows change_counter will change each time the row is editted
- Given the above rules
- At 9am, you scan and the highest change_counter is "9am" for product 123
- At 10am the user edits product 123 - so it's change_counter is now "10am"
- At 10:30am the user edits product 456 - so it's change_counter is now "10:30am"
- At 1pm the user edits product 123 again - so it's change_counter is now "1pm"
If you now poll again with q: { "_$change_counter": "9am" } the rows will be returned in the order product 456/10:30am and then product 123/1pm
More
The above is describing using classic HTTP GET/POST and polling for changes. FD1 can send streaming data over a websocket too. This is overkill for many websites, but may be useful for high volume websites that need to react instantly to changes. See Worked Example: Product Search for an example. This should work with your APIkey