Sync Service
Introduction
The Sync Service is a custom API whose primary function is to provide a REST endpoint for integrating with Galaxy for the purpose of synchronizing data with online shops. As such, the Sync service is also known as the WebShop API.
Sync provides three types of endpoints:
- Misc Lookups
- Entity lists, with synchronization
- “Online” calls, to send data to the back-end in real time
All the endpoints provided by the Sync API are geared towards enabling the client create a Commercial Entry payload and communicate purchases back to Galaxy. It also enables the client to create and post Customer data to the back-end.
Anatomy of a Sync solution
Sync is designed primarily for offline use. Clients are meant to sychronize their database using bulk updates at predefined intervals. Sync provides a synchronization mechanism based on Revision Numbers for several entities, including customers, items ( products ), item features and stock balances and others.
An API client is meant, in general terms, to implement a simple synchronization workflow:
- Sync misc Lookups
- Sync Entity tables, most commonly in a pre-defined order
- Construct the appropriate purchase or customer payload[s]
- Post the purchase and/or customer data to the server
This sequence is meant to be repeated at regular intevals during the day, to keep the two systems synchronized.
Alternatively, the client developer has the option of posting purchase or customer data to the server in real-time, depending on their needs for the solution at hand.
There is also a recent extension to the Galaxy API, that allows the back-end to perform Http Requests to pre-defined URLs when certain events occur in the system ( Galaxy WebHooks ). This is another available option for the client developer, should they need to keep the two systems in sync in near-real-time.
Galaxy WebHooks could be used to trigger synchronization from the client’s side. Note however, that they cannot, in no shape of form, be considered replacements of the synchronization mechanism, but rather useful extensions.
Galaxy Web Scenarios
The Galaxy platform supports e-shop synchronization scenarios, under Web Scenarios. A configured and working Web Scenario is a base requirement for the Sync API.
Unless there is a functioning Web Scenario defined as the default Web Scenario, all calls to the Sync service must include the WebScenID URL parameter.
WebScenID: alphanumeric identifier of a configured WebScenario
The Sync API provides an endpoint from which a list of configured Web Scenarios can be retrieved:
/services/sync/webscenarios
Response:
[
{
"IsDefault": 1,
"Type": 2,
"CompanyID": "743d7942-4ccb-474b-b140-06011f6795cc",
"ID": "d6c30ca7-e52f-4a47-a567-8a5545030936",
"Code": "Default B2C",
"Description": "Default B2C Web Scenario"
},
...
]
Web Scenarios define several aspects regarding how the integration will work. For example, the types of purchase documents produced, transport types, product categories exposed to the API and several other features can only be administered through a Web Scenario.
In addition, in a Galaxy installation we can have more than one companies, and more than one functioning Web Scenarios. Unless the Web Scenario we need to use is the default, we always need to pass the Web Scenario ID to the WebScenID URL parameter.
Synchronizing Lookups
The structure of a sales document ( we will be referring to it as Commercial Entry in this document ) contains placeholders where various values originating from lookup lists are to be inserted. Those can range from city and region codes to dispatch purposes and payment types.
Lookups are typically static lists in the Galaxy platform. As such, they only be retrieved and cached once.
The endpoints returning Lookup lists support GET Http Requests, and a return an array it items, typically sharing the same payload schema.
The generic structure of a Lookup URL is:
/services/sync/{LookupName}
Typically, the response payload is:
[
{
"ID": "String",
"Code": "String",
"Description": "String"
}
]
For example, to retrieve the Countries lookup, we would execute a GET request to /services/sync/countries
:
Response:
[
{
"ID": "e51120fe-d246-460d-b8a6-06e4e47ff281",
"Code": "JP",
"Description": "Ιαπωνία"
},
{
"ID": "d55d61a4-99ad-424a-9484-0c6d81920c57",
"Code": "HU",
"Description": "Ουγγαρία"
},
{
"ID": "25c27d9c-3a91-445d-867f-0ed3c2ca335c",
"Code": "LT",
"Description": "Λιθουανία"
},
{
"ID": "06cddf3b-cd0f-435a-9a14-1083014b3a12",
"Code": "IQ",
"Description": "Ιράκ"
},
{
"ID": "dd6f7e9a-f70d-4dc5-a9d1-1183bcb3ec70",
"Code": "CU",
"Description": "Κούβα"
},
...
]
Note: All Lookups operate in the same way, and return the same payload schema.
The Sync API exposes the following lookup lists:
- Countries
- Prefectures
- Cities
- Currencies
- PaymentMethods
- Charges
- DispatchPurposes
- ShippingMethods
- Agencies
Synchronizing Entity Lists
Entity Lists originate from data in a database, and their contents might change at any time. Synchronizing Entity lists is a little more involved, since fetching the complete dataset every time we sync would lead to possible performance degradation.
The Galaxy platform introduces the concept of a Revision Number, to provide the ability for clients to retrieve only modified data when synchronizing an entity list.
In general:
- Every row in the database, includes a Revision Number integer field
- Every created or modified row gets it’s Revision Number incremented to an auto-number value.
- A client retrieves changed or created rows for a list by providing the max Revision Number found in it’s local data, or zero if it has none
- The API will examine the Revision Number parameter, and only return rows that have a greater revision number
Let’s see a more concrete example. Consider a client that needs to maintain a local copy of all customers in our database, and synchronize changes when they occur:
- The client has no data in their Customers table
- The client issues a GET request at
/services/sync/customers?RevisionNumber=0
- The client stores the data in it’s local database
- The largest revision number retrieved is 3
- At this point, an operator modifies a customer in the Galaxy back-end
- The customer’s revision number is updated to a value that is the greatest in the customers table, let’s assume it’s 4.
- The client attempts to sync at some pre-defined interval
- Now, the
max(Revision Number)
in the clients local DB is 3, so it is included in the RevisionNumber parameter - The API will now only select rows whose Revision Number is greater than 3
- The API returns a single row, the customer that changed between sync invocations
- The client stores the data in it’s local database
- The largest revision number retrieved is now 4
Following this procedure, we can ensure that clients will only ever retrieve changes to their locally cached dataset, rather than the full data which could be thousands of rows to process, drastically minimizing the hardware resources and time required to synchronize the data between the two systems.
Entities & Lookups, relations
There are four distinct areas of data the Sync API is primarily involved with:
- Customers
- Companies
- Items
- Commercial Entries
Each area consists of a number of Lookups and Entities, working togetehr to describe a certain area of functionality. In this section, we will attempt to analyse those areas, and inspect the relationships between the participating entities and lookups in each one.
Customers
Customers are relatively simple entities, consisting of:
- Basic Customer data ( name, company they belong to, comments etc. )
- Customer Sites, describing contact details like addresses, telephones, emails etc.
The two lists can be found at:
/services/sync/customers
/services/sync/customersites
Todo: Ref links
Companies
Companies are similar in form with Customers. They also are made up of just two lists:
- Basic Company data ( name, code, description and Tax no )
- Company Sites ( simple entity containing basically only a name and a code )
The two lists can be found at:
/services/sync/companies
/services/sync/companysites
Todo: Ref links
Items
Items are perhaps the most complex Entity in the API. It consists of several lists, all working together to describe a single product for sale.
Those include:
- Items
- Item Categories
- Item Attributes
- Item Dimensions
- Item Alter Codes
- Item Balances
- Item Images
Item Categories
In Galaxy item categories are a tree of infinite nesting, although in real-life deployments we seldom see anything beyond two or three levels of nesting.
The Item payload itself maintains an array of category assosciations in the form:
"ItemCategories": [
{
"CategoryLeafID": "78cfaaf3-60ed-4db2-847c-d6394c3692c0",
"CategoryRootID": "78cfaaf3-60ed-4db2-847c-d6394c3692c0",
"IsPerCompany": 1
},
{
"CategoryLeafID": "eb7c4691-097d-450e-9f72-e3d3c288bfec",
"CategoryRootID": "eb7c4691-097d-450e-9f72-e3d3c288bfec",
"IsPerCompany": 1
}
]
As we can see, on the Item itself, we store the Root and Leaf categories for each item, and whether the ascociation is specific per company and not for all companies that stock the item.
The Categories payload is an array of category items:
[
{
"ParentNodeID": "4fd95611-d6af-43e6-b397-73f6be1516fa",
"LevelOfNode": 3,
"CatLanguages": [],
"ID": "01cad8e6-3e96-4d1b-997b-0285049ec654",
"Code": "600-01-02",
"Description": "Γάλα",
"RevisionNumber": 0
},
{
"ParentNodeID": "78cfaaf3-60ed-4db2-847c-d6394c3692c0",
"LevelOfNode": 2,
"CatLanguages": [],
"ID": "03be03e9-966e-4196-9672-0bad3f09f3a3",
"Code": "300-99",
"Description": "Λοιπά Brand",
"RevisionNumber": 0
},
...
]
Inside the Item payload, we maintain the values for the ID property of the root and final leaf categories we assosciate the Item with.
Item Attributes
Item Attributes are named groups of values, identifying specific characteristics of items. They can range from manufacturer name, to types of daw for pastries, screen sizes in inches etc.
The Item payload also maintains an array of attribute items, just like it does for categories:
"ItemAttributes": [
{
"ID": "d2873c5c-cad8-49fa-8f35-0212b590f8f3",
"AttrID": "18236384-2671-45ba-acf8-2f7bcf89152e",
"FldBoolean": null,
"FldDateTime": null,
"FldDecimal": null,
"FldString": null,
"FldAttrValueID": "df7460fb-31f7-449f-b912-3808639cc410"
},
{
"ID": "844749ee-4ca3-4727-ad10-0e5ea70e46ad",
"AttrID": "e4a57e81-287d-4ddf-b1e8-10be9e63d63e",
"FldBoolean": null,
"FldDateTime": null,
"FldDecimal": null,
"FldString": null,
"FldAttrValueID": "52605325-d296-404d-b02b-a8fa333e21b4"
}
]
The keys that interest us and identify an attribute group and a specific value are:
AttrID - points to the ID property of an ItemAttribute FldAttrValueID - points to the exact value off the attribute values list
Consider our first attribute item in the array. Lets retrieve /services/sync/itemattributes
:
[
{
"Kind": 7,
"AttrValues": [
{
"ID": "df7460fb-31f7-449f-b912-3808639cc410",
"Code": "Women",
"Description": "Women",
"Color": null,
"AttrValuesLanguages": []
},
{
"ID": "d45a0923-1050-42cf-b69f-9390a1b2823c",
"Code": "Men",
"Description": "Men",
"Color": null,
"AttrValuesLanguages": []
},
{
"ID": "ec9a1412-061b-4b56-8c5f-59fdfcd1af4c",
"Code": "Kids",
"Description": "Kids",
"Color": null,
"AttrValuesLanguages": []
},
{
"ID": "bb0693a4-ac7b-4bde-a2ba-f6d991090698",
"Code": "Unisex",
"Description": "Unisex",
"Color": null,
"AttrValuesLanguages": []
}
],
"AttrLanguages": [],
"ID": "18236384-2671-45ba-acf8-2f7bcf89152e",
"Code": "ΚΛΦ",
"Description": "Κατηγορία Καλλυντικών",
"RevisionNumber": 0
}
]
As we can see, we can find the Attribute whose ID is 18236384-2671-45ba-acf8-2f7bcf89152e
and a nested Value with ID df7460fb-31f7-449f-b912-3808639cc410
. Our Item’s attribute value is therefore:
{
"ID": "df7460fb-31f7-449f-b912-3808639cc410",
"Code": "Women",
"Description": "Women",
"Color": null,
"AttrValuesLanguages": []
}
As you can see, Item Attributes are mainly used for grouping or categorizing Items.
Item Dimensions
Item Dimensions are very similar to Attributes, but are typically used in Galaxy for qualitative categorization, for item characteristics like Size or Color. For example, the manufacturer is not a dimension for a mobile phone, but the screen size is.
The payload for the /services/sync/itemdimensions
list is very similar to attributes:
Item Alter Codes
Item Balances
Item Images