strapi-plugin-config-sync icon indicating copy to clipboard operation
strapi-plugin-config-sync copied to clipboard

Import of custom content type entry has other `id` than on exported system

Open jnachtigall opened this issue 3 years ago • 5 comments

Bug report

Describe the bug

We use this plugin (thank you) to have a consistent DB (data, settings, custom content types and entries) for our whole team.

We use Postgres as DB.

Steps to reproduce the behavior

  1. I did an export of everything and pushed this in git. There was just one entry type for one custom content type. On my system this entry type had the id 3.
  2. Colleague B did an import. On his system the id for this entry was now 1.

I guess that I had 3 because I did create 2 other entries before which I deleted before I did an export.

Now when I did an API GET request like http://localhost:1337/api/our-custom-content-type/3 it worked on my system, but on colleague B she got a 404. She needed to change it to http://localhost:1337/api/our-custom-content-type/1

Expected behavior

To have a consistent data sharing the IDs should be in sync. Especially since those are used for API access.

System

  • Node.js version: 16.13.0
  • NPM version: 8.3.1
  • Strapi version: 4.3.0
  • Plugin version: 1.0.2
  • Database: Postgres Docker image
  • Operating system: WSL2 in Windows

Additional context

Not sure this is a bug or a feature 🙃 But having ever-changing IDs makes it hard to consume the strapi backend API from an external frontend in a consistent way.

jnachtigall avatar Aug 11 '22 07:08 jnachtigall

Hi @jnachtigall

I totally get where you're coming from. Though what you're proposing is simply impossible. As you have noticed the plugin does not take in to account what ID a record is on.

The reason for this is the same as why the readme states you can't use id as the uid of your custom config type. Quote:

Auto-increment does not play nice when you try to match entries across different databases.

That's why the plugin matches entries by their uid value. You're using the custom config types, so you are probably aware of the records having a uid. A unique identifier. Something that is unique to the specific record, though the same on all the envs (unlike the id).

If you want to consume these records through the API you could just filter on the UID, instead of the ID. So your API request would look something like this:

http://localhost:1337/api/our-custom-content-type?uid-field-name=uid-value

Hopes this helps you out :)

boazpoolman avatar Aug 12 '22 06:08 boazpoolman

Thanks for explaning, @boazpoolman So the uid matching is a feature of the config sync plugin? Because I cannot find any infos about it when reading through https://docs.strapi.io/developer-docs/latest/developer-resources/database-apis-reference/rest-api.html#endpoints

Reading through the UID part of the README of the config sync plugin I am still puzzled how the API request using the uid would look like because I have a combined uid key which is:

customTypes: [
  {
    configName: "ctform",
    queryString: "api::ct-form-form.ct-form-form",
    uid: ["formId", "baseUrl"],
  },
]

So to request an entry like the following below, how would the request look like?

{
  "data": {
    "id": 1,
    "attributes": {
      "baseUrl": "https://www.ctform.org/ctform",
      "successUrl": "https://www.ctform.org/ctform/anfrage-versendet.html",
      "errorUrl": "https://www.ctform.org/ctform/anfrage-fehler.html",
      "formId": 564,
      "createdAt": "2022-08-11T07:05:03.822Z",
      "updatedAt": "2022-08-11T07:05:03.822Z",
      "publishedAt": "2022-08-04T07:12:41.031Z"
    }
  },
  "meta": {}
}

Would it be http://localhost:1337/api/ctform?uid-field-name=[564,"https://www.ctform.org/ctform"] ? (well, this but using the qs package for proper encoding I guess) ?

I think the README misses the documentation or at least examples on how to use the uid in API requests.

jnachtigall avatar Aug 17 '22 10:08 jnachtigall

Hi @jnachtigall,

No matching by UID is not something that Strapi is promoting in their docs. That's because it only really comes into play when you try to match entries across different databases.

You're using the combined uid for your config type. So in that case you could filter on both values in your API request. So the request would look like: http://localhost:1337/api/ctform?formId=564&baseUrl=https://www.ctform.org/ctform.

What you see in the request URL is pretty much the same thing the plugin does behind the scenes when you use the combined uid. It will filter on field values.

I think the README misses the documentation or at least examples on how to use the uid in API requests.

I haven't added this as I think most people use this plugin to sync data that is not consumed through the content API.

Also if your formId value is a unique value in the ctform table you don't have to use the combined uid. You can just use formId as the uid and query the API by filtering on just that value. Like this: http://localhost:1337/api/ctform?formId=564

Hope this clears it up for you :)

boazpoolman avatar Aug 17 '22 14:08 boazpoolman

Hi @boazpoolman

thanks, I see. However, http://localhost:1337/api/ctform?formId=564&baseUrl=https://www.ctform.org/ctform is not working (404) and then also after changing the uid to single formId is not working either (also 404). I also did use ctforms (plural) instead of ctform (singular) in the URL. Again, no success. Am I missing something here?

PS Are you sure one can simply query using the old-fashion ?param=value way? Looking at the docs at https://docs.strapi.io/developer-docs/latest/developer-resources/database-apis-reference/rest/filtering-locale-publication.html#filtering the strapi API only allows a more complex way of filtering/querying like http://localhost:1337/api/ctforms?filters[formId][$eq]=564. This works but albeit being more complex it returns an array with a single entry instead of a single entry like ``http://localhost:1337/api/ctform/1`

jnachtigall avatar Aug 22 '22 06:08 jnachtigall

Ah. I think my query syntax was incorrect. It should probably be with the more complex filter structure. If that is too much hassle, you could also create your own custom endpoint to do the same, but with formId as part of the URL instead of as a URL param

boazpoolman avatar Aug 22 '22 08:08 boazpoolman

I'm gonna be closing this issue as it won't be fixed. If you have any other questions about this topic or another feel free to re-open the issue, or open another.

boazpoolman avatar Nov 27 '22 13:11 boazpoolman