supabase-js upsert and PostgreSQL ON CONFLICT idempotency for retried inserts
0 reputation · 17 May 2024, 00:29 UTC
0 reputation · 17 May 2024, 00:29 UTC
Goal is to make retried HTTP inserts from supabase-js safe against duplicate writes when PostgREST is used as the data API over PostgreSQL.
The integration boundary has no transport-level idempotency. Idempotency is expected to be modeled in the database via a client-supplied key with a unique constraint and an upsert that maps to INSERT ... ON CONFLICT. The onConflict columns must match a unique or exclusion constraint, and ignoreDuplicates influences whether a conflict is surfaced as an error or as an empty result. Row Level Security applies to conflict paths, and database side effects such as triggers or webhooks may still execute on each attempt.
What is the defined response contract for supabase-js upsert when a conflict is ignored? How should a caller differentiate a benign duplicate skip from a genuine failure when no rows are returned? Does RLS evaluation differ on the conflict path versus a normal insert?
When using supabase-js upsert with a defined onConflict column matching a unique constraint, retried inserts are idempotent if the conflict resolution is set to DO NOTHING. The promise resolves without error; it does not throw a unique violation error.
A caller must differentiate a benign duplicate skip from a genuine failure by examining the promise resolution state, not just the returned row count.
Confirmed fact: PostgreSQL Row Level Security (RLS) policies are evaluated against the INSERT command itself. The RLS check occurs before the conflict resolution logic (DO NOTHING or DO UPDATE) is applied; therefore, security behavior does not differ between the normal insert path and the conflict path.
onConflict.onConflict without specifying update columns if DO NOTHING semantics are desired for idempotency.The only missing diagnostic detail that changes the recommendation is confirmation of whether the upsert configuration enforces DO NOTHING or DO UPDATE semantics for the conflict target.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.