For developers

Data synchronization

Synchronization

Data synchronization between different systems is always a challenge for a developer, as building a reliable ETL is time-consuming and not always convenient. You always need to keep track of the "source of truth" and store record identifiers in related systems for a subsequent upsert strategy (update or insert).

remoteId

Keruy on an architectural level adds such a convenient remoteId field to the main entities via API

This is the data identifier from your "source of truth". It is not required, but if you pass it, the value must be unique.

remoteId allows you to use it for subsequent exchanges during data synchronization. Thanks to this, you do not need to store the id value from Keruy on your side to synchronize data in Keruy.

Upsert mutations

In addition to standard create/update/delete mutations in the Keruy API, there are also separate upsert mutations that allow you to synchronize data more easily. They work on the update or insert principle. That is, you simply call the upsert mutation you need with the required identifier or your remoteId and Keruy itself will decide whether this record needs to be created or updated. Currently, our API provides the following upsert mutations

  • upsertItem

  • upsertAddress

  • upsertLocation

  • upsertContragent

  • upsertDocument

  • upsertDocumentItem

  • upsertTaxon

Example with items

For example, let's take the synchronization of items from your database to Keruy.

Request

mutation ($input: UpsertItemInput!) {
  upsertItem(input: $input) {
    id
    remoteId
    name
    sku
    basePrice
  }
}
mutation ($input: UpsertItemInput!) {
  upsertItem(input: $input) {
    id
    remoteId
    name
    sku
    basePrice
  }
}
mutation ($input: UpsertItemInput!) {
  upsertItem(input: $input) {
    id
    remoteId
    name
    sku
    basePrice
  }
}

Variables

{
  "input": {
    "remoteId": "your_db_id",
    "context": "CARGO",
    "name": "Вино Шардоне, Колоніст / Chardonnay, Kolonist, біле сухе 13.5% 0.75л",
    "basePrice": 999
  }
}
{
  "input": {
    "remoteId": "your_db_id",
    "context": "CARGO",
    "name": "Вино Шардоне, Колоніст / Chardonnay, Kolonist, біле сухе 13.5% 0.75л",
    "basePrice": 999
  }
}
{
  "input": {
    "remoteId": "your_db_id",
    "context": "CARGO",
    "name": "Вино Шардоне, Колоніст / Chardonnay, Kolonist, біле сухе 13.5% 0.75л",
    "basePrice": 999
  }
}

Response

{
  "data": {
    "upsertItem": {
      "basePrice": "999",
      "id": "9dc7f7af-abe6-4e31-89e4-057f0a9c7c84",
      "name": "Вино Шардоне, Колоніст / Chardonnay, Kolonist, біле сухе 13.5% 0.75л",
      "remoteId": "your_db_id",
      "sku": "1000014"
    }
  }
}
{
  "data": {
    "upsertItem": {
      "basePrice": "999",
      "id": "9dc7f7af-abe6-4e31-89e4-057f0a9c7c84",
      "name": "Вино Шардоне, Колоніст / Chardonnay, Kolonist, біле сухе 13.5% 0.75л",
      "remoteId": "your_db_id",
      "sku": "1000014"
    }
  }
}
{
  "data": {
    "upsertItem": {
      "basePrice": "999",
      "id": "9dc7f7af-abe6-4e31-89e4-057f0a9c7c84",
      "name": "Вино Шардоне, Колоніст / Chardonnay, Kolonist, біле сухе 13.5% 0.75л",
      "remoteId": "your_db_id",
      "sku": "1000014"
    }
  }
}

In this case, Keruy used the value of your remoteId and created a corresponding record in the items table. ID and SKU were generated automatically, but remoteId can be used for subsequent data exchanges.

For example, the price of a product has changed, and you pass the same mutation, but with different variables (basePrice changed)

Request

{
  "input": {
    "remoteId": "your_db_id",
    "context": "CARGO",
    "name": "Вино Шардоне, Колоніст / Chardonnay, Kolonist, біле сухе 13.5% 0.75л",
    "basePrice": 699
  }
}
{
  "input": {
    "remoteId": "your_db_id",
    "context": "CARGO",
    "name": "Вино Шардоне, Колоніст / Chardonnay, Kolonist, біле сухе 13.5% 0.75л",
    "basePrice": 699
  }
}
{
  "input": {
    "remoteId": "your_db_id",
    "context": "CARGO",
    "name": "Вино Шардоне, Колоніст / Chardonnay, Kolonist, біле сухе 13.5% 0.75л",
    "basePrice": 699
  }
}

Response

{
  "data": {
    "upsertItem": {
      "basePrice": "699",
      "id": "9dc7f7af-abe6-4e31-89e4-057f0a9c7c84",
      "name": "Вино Шардоне, Колоніст / Chardonnay, Kolonist, біле сухе 13.5% 0.75л",
      "remoteId": "your_db_id",
      "sku": "1000014"
    }
  }
}
{
  "data": {
    "upsertItem": {
      "basePrice": "699",
      "id": "9dc7f7af-abe6-4e31-89e4-057f0a9c7c84",
      "name": "Вино Шардоне, Колоніст / Chardonnay, Kolonist, біле сухе 13.5% 0.75л",
      "remoteId": "your_db_id",
      "sku": "1000014"
    }
  }
}
{
  "data": {
    "upsertItem": {
      "basePrice": "699",
      "id": "9dc7f7af-abe6-4e31-89e4-057f0a9c7c84",
      "name": "Вино Шардоне, Колоніст / Chardonnay, Kolonist, біле сухе 13.5% 0.75л",
      "remoteId": "your_db_id",
      "sku": "1000014"
    }
  }
}

As you can see, the record has been updated with the new price value

Identifier priorities

For upsert mutations, identifier priority is very important; if you decide to pass both id and remoteId in 1 request, the main synchronization key will be id

You can find more details about identifier priorities in the annotations for the API documentation of each specific upsert mutation

Related articles