Mutations
Create, update, and delete entities from Server Components with the server client or from Client Components with React Query hooks.
Server (Upsert & Delete)
Upsert
Create or update an entity using Pylo's __search_value pattern. If a record matching the search is
found, it's updated — otherwise a new record is created.
1
2
3
4
5
6
7
8
9
10
11
const result = await pylo.invoice.upsert({
__search_value: {
field: 'invoice_number',
value: 'INV-001',
not_found_behavior: 'create',
},
invoice_number: 'INV-001',
amount_net: 1000,
});
// result: { id: string }With relations
Use _set to connect related entities during upsert:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
await pylo.invoice.upsert({
__search_value: {
field: 'invoice_number',
value: 'INV-001',
not_found_behavior: 'create',
},
invoice_number: 'INV-001',
amount_net: 1500,
customer_set: {
__search_value: {
field: 'customer_number',
value: 'C-001',
not_found_behavior: 'create',
},
name: 'Acme Corp',
},
});Delete
1
2
const result = await pylo.invoice.delete(['invoice-uuid-1', 'invoice-uuid-2']);
// result: { success: boolean }Client (React Query Hooks)
usePyloUpsert
Create or update entities from Client Components. Automatically invalidates list queries on success.
1
2
3
4
5
6
7
8
'use client';
import { pylo } from "@/lib/pylo-hooks";
const upsert = pylo.usePyloUpsert('invoice');
await upsert.mutateAsync({ __search_value: { field: 'invoice_number', value: 'INV-001',
not_found_behavior: 'create', }, invoice_number: 'INV-001', amount_net: 1000, });usePyloDelete
Delete entities by ID. Automatically invalidates list queries on success.
1
2
3
4
5
6
7
'use client';
import { pylo } from "@/lib/pylo-hooks";
const deleteMutation = pylo.usePyloDelete('invoice');
deleteMutation.mutate(['invoice-uuid']);Cache Invalidation
Mutations (usePyloUpsert and usePyloDelete) automatically invalidate all queries for the same
entity. List views refresh automatically after creates, updates, or deletes.
Query key structure:
- Lists:
['pylo', entityName, 'list', options] - Infinite lists:
['pylo', entityName, 'infiniteList', options] - By ID:
['pylo', entityName, 'byId', id, options]
Mutations invalidate the prefix ['pylo', entityName], which covers all of the above.