1"use strict";(self.webpackChunkq_01_docs=self.webpackChunkq_01_docs||[]).push([[6416],{8884:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>s,default:()=>p,frontMatter:()=>i,metadata:()=>d,toc:()=>l});var r=t(7624),a=t(2172);const i={title:"Partial Updates",sidebar_label:"Partial Updates (PATCH)",sidebar_position:4,description:"Field-level updates with PATCH operations"},s="Partial Updates (PATCH)",d={id:"products/map.q01.io/core-api-platform-v4/write-patterns/partial-updates",title:"Partial Updates",description:"Field-level updates with PATCH operations",source:"@site/docs/products/map.q01.io/core-api-platform-v4/04-write-patterns/partial-updates.md",sourceDirName:"products/map.q01.io/core-api-platform-v4/04-write-patterns",slug:"/products/map.q01.io/core-api-platform-v4/write-patterns/partial-updates",permalink:"/docs/products/map.q01.io/core-api-platform-v4/write-patterns/partial-updates",draft:!1,unlisted:!1,tags:[],version:"current",sidebarPosition:4,frontMatter:{title:"Partial Updates",sidebar_label:"Partial Updates (PATCH)",sidebar_position:4,description:"Field-level updates with PATCH operations"},sidebar:"mapSidebar",previous:{title:"Update Operations (PUT)",permalink:"/docs/products/map.q01.io/core-api-platform-v4/write-patterns/update-operations"},next:{title:"Delete Operations (DELETE)",permalink:"/docs/products/map.q01.io/core-api-platform-v4/write-patterns/delete-operations"}},c={},l=[{value:"Overview",id:"overview",level:2},{value:"Basic PATCH Request",id:"basic-patch-request",level:2},{value:"Single Field Update",id:"single-field-update",level:3},{value:"PATCH vs PUT",id:"patch-vs-put",level:2},{value:"Safety Comparison",id:"safety-comparison",level:3},{value:"Comparison Table",id:"comparison-table",level:3},{value:"Multiple Field Updates",id:"multiple-field-updates",level:2},{value:"Update Several Fields",id:"update-several-fields",level:3},{value:"Common PATCH Patterns",id:"common-patch-patterns",level:2},{value:"Pattern 1: Price Update",id:"pattern-1-price-update",level:3},{value:"Pattern 2: Toggle Active Status",id:"pattern-2-toggle-active-status",level:3},{value:"Pattern 3: Increment Counter",id:"pattern-3-increment-counter",level:3},{value:"Pattern 4: Bulk Field Update",id:"pattern-4-bulk-field-update",level:3},{value:"JavaScript Implementation",id:"javascript-implementation",level:2},{value:"Product Service with PATCH",id:"product-service-with-patch",level:3},{value:"React Hook for PATCH",id:"react-hook-for-patch",level:3},{value:"COD_ON_OFF Validation",id:"cod_on_off-validation",level:2},{value:"Modifiable Fields",id:"modifiable-fields",level:3},{value:"PATCH with UPDATE_CASCADE",id:"patch-with-update_cascade",level:2},{value:"Cascading Updates",id:"cascading-updates",level:3},{value:"Best Practices",id:"best-practices",level:2},{value:"\u2705 DO:",id:"-do",level:3},{value:"\u274c DON'T:",id:"-dont",level:3},{value:"Performance Considerations",id:"performance-considerations",level:2},{value:"PATCH vs PUT Performance",id:"patch-vs-put-performance",level:3},{value:"Conditional Updates",id:"conditional-updates",level:2},{value:"Update Only If Condition Met",id:"update-only-if-condition-met",level:3},{value:"Summary",id:"summary",level:2},{value:"Related Concepts",id:"related-concepts",level:2}];function o(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,a.M)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h1,{id:"partial-updates-patch",children:"Partial Updates (PATCH)"}),"\n",(0,r.jsx)(n.h2,{id:"overview",children:"Overview"}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.strong,{children:"PATCH"})," operations update specific fields without affecting others. This is the ",(0,r.jsx)(n.strong,{children:"recommended"})," method for most updates, as it's safer than PUT (which replaces the entire record)."]}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Endpoint:"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"PATCH /api/v4/core/{dim}/{dim_id}\nContent-Type: application/json\nAuthorization: Bearer {token}\n"})}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Behavior:"})}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Updates ONLY specified fields"}),"\n",(0,r.jsx)(n.li,{children:"Other fields remain unchanged"}),"\n",(0,r.jsx)(n.li,{children:"Sets TREC='M' (Modified)"}),"\n",(0,r.jsx)(n.li,{children:"Sets LDATA, LOWNER (last update audit fields)"}),"\n",(0,r.jsx)(n.li,{children:"Validates COD_ON_OFF='M' permissions"}),"\n",(0,r.jsx)(n.li,{children:"Executes UPDATE_CASCADE operations"}),"\n",(0,r.jsx)(n.li,{children:"Publishes update event to outbox"}),"\n"]}),"\n",(0,r.jsxs)(n.p,{children:["\u2705 ",(0,r.jsx)(n.strong,{children:"Recommended:"})," Use PATCH for single/few field updates."]}),"\n",(0,r.jsx)(n.h2,{id:"basic-patch-request",children:"Basic PATCH Request"}),"\n",(0,r.jsx)(n.h3,{id:"single-field-update",children:"Single Field Update"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Request:"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:'PATCH /api/v4/core/PRD/123\nAuthorization: Bearer eyJhbGc...\nContent-Type: application/json\n\n{\n "data": {\n "XPRD02": 89.99 // Only update price\n }\n}\n'})}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Response:"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-json",children:'{\n "status": "success",\n "data": {\n "PRD_ID": 123,\n "XPRD01": "Widget Pro", // Unchanged\n "XPRD02": 89.99, // Updated\n "XPRD03": "PRD-2025-001", // Unchanged\n "XPRD04": "Professional widget", // Unchanged\n "XPRD05": "cat_electronics", // Unchanged\n "XPRD06": true, // Unchanged\n "XPRD09": 100, // Unchanged\n "TREC": "M", // Changed to \'M\'\n "CDATA": "20251219153045", // Original creation time\n "OWNER": "[email protected]", // Original creator\n "LDATA": "20251219160000", // Last update timestamp\n "LOWNER": "[email protected]" // Last updater\n }\n}\n'})}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Database SQL:"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sql",children:"UPDATE TB_ANAG_PRD00\nSET XPRD02 = 89.99,\n TREC = 'M',\n LDATA = '20251219160000',\n LOWNER = '[email protected]'\nWHERE PRD_ID = 123;\n"})}),"\n",(0,r.jsx)(n.h2,{id:"patch-vs-put",children:"PATCH vs PUT"}),"\n",(0,r.jsx)(n.h3,{id:"safety-comparison",children:"Safety Comparison"}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.strong,{children:"Scenario:"})," Update only the price of a product."]}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"\u274c PUT (unsafe):"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:'PUT /api/v4/core/PRD/123\n{\n "data": {\n "XPRD01": "Widget Pro",\n "XPRD02": 89.99, // Only this changed\n "XPRD04": "Professional widget",\n "XPRD05": "cat_electronics",\n "XPRD06": true,\n "XPRD09": 100\n // Must include ALL fields\n }\n}\n'})}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Problems:"})}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Must fetch current record first"}),"\n",(0,r.jsx)(n.li,{children:"Must include ALL fields"}),"\n",(0,r.jsx)(n.li,{children:"Risk of data loss if fields omitted"}),"\n",(0,r.jsx)(n.li,{children:"Verbose request body"}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"\u2705 PATCH (safe):"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:'PATCH /api/v4/core/PRD/123\n{\n "data": {\n "XPRD02": 89.99 // Only this changed\n }\n}\n'})}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Benefits:"})}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"No need to fetch current record"}),"\n",(0,r.jsx)(n.li,{children:"Only include changed field"}),"\n",(0,r.jsx)(n.li,{children:"No risk of data loss"}),"\n",(0,r.jsx)(n.li,{children:"Minimal request body"}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"comparison-table",children:"Comparison Table"}),"\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Aspect"}),(0,r.jsx)(n.th,{children:"PUT"}),(0,r.jsx)(n.th,{children:"PATCH"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.strong,{children:"Fields updated"})}),(0,r.jsx)(n.td,{children:"ALL fields"}),(0,r.jsx)(n.td,{children:"ONLY specified fields"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.strong,{children:"Other fields"})}),(0,r.jsx)(n.td,{children:"Set to NULL/default if missing"}),(0,r.jsx)(n.td,{children:"Unchanged"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.strong,{children:"Fetch required"})}),(0,r.jsx)(n.td,{children:"\u2705 Yes (to avoid data loss)"}),(0,r.jsx)(n.td,{children:"\u274c No"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.strong,{children:"Request size"})}),(0,r.jsx)(n.td,{children:"Large (all fields)"}),(0,r.jsx)(n.td,{children:"Small (only changed fields)"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.strong,{children:"Safety"})}),(0,r.jsx)(n.td,{children:"\u26a0\ufe0f Risk of data loss"}),(0,r.jsx)(n.td,{children:"\u2705 Safe"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.strong,{children:"Use case"})}),(0,r.jsx)(n.td,{children:"Full record replacement"}),(0,r.jsx)(n.td,{children:"Single/few field updates"})]})]})]}),"\n",(0,r.jsx)(n.h2,{id:"multiple-field-updates",children:"Multiple Field Updates"}),"\n",(0,r.jsx)(n.h3,{id:"update-several-fields",children:"Update Several Fields"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Request:"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:'PATCH /api/v4/core/PRD/123\n{\n "data": {\n "XPRD02": 89.99, // Update price\n "XPRD06": false, // Deactivate\n "XPRD09": 0 // Set stock to zero\n }\n}\n'})}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Result:"})}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"XPRD02 changed to 89.99"}
1),"\n",(0,r.jsx)(n.li,{children:"XPRD06 changed to false"}),"\n",(0,r.jsx)(n.li,{children:"XPRD09 changed to 0"}),"\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.strong,{children:"All other fields unchanged"})}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"common-patch-patterns",children:"Common PATCH Patterns"}),"\n",(0,r.jsx)(n.h3,{id:"pattern-1-price-update",children:"Pattern 1: Price Update"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Update product price:"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-javascript",children:"async function updateProductPrice(productId, newPrice) {\n const response = await fetch(`${apiBase}/api/v4/core/PRD/${productId}`, {\n method: 'PATCH',\n headers: {\n 'Authorization': `Bearer ${token}`,\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify({\n data: { XPRD02: newPrice }\n })\n });\n\n return response.json();\n}\n\n// Usage\nawait updateProductPrice(123, 89.99);\n"})}),"\n",(0,r.jsx)(n.h3,{id:"pattern-2-toggle-active-status",children:"Pattern 2: Toggle Active Status"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Activate/deactivate product:"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-javascript",children:"async function toggleProductActive(productId) {\n // 1. Fetch current status\n const response = await fetch(`${apiBase}/api/v4/core/PRD/${productId}`, {\n headers: { 'Authorization': `Bearer ${token}` }\n });\n const current = await response.json();\n\n // 2. Toggle\n const newStatus = !current.data.XPRD06;\n\n // 3. PATCH\n const result = await fetch(`${apiBase}/api/v4/core/PRD/${productId}`, {\n method: 'PATCH',\n headers: {\n 'Authorization': `Bearer ${token}`,\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify({\n data: { XPRD06: newStatus }\n })\n });\n\n return result.json();\n}\n"})}),"\n",(0,r.jsx)(n.h3,{id:"pattern-3-increment-counter",children:"Pattern 3: Increment Counter"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Increment stock quantity:"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-javascript",children:"async function incrementStock(productId, quantity) {\n // 1. Fetch current stock\n const response = await fetch(`${apiBase}/api/v4/core/PRD/${productId}`, {\n headers: { 'Authorization': `Bearer ${token}` }\n });\n const current = await response.json();\n\n // 2. Calculate new stock\n const newStock = current.data.XPRD09 + quantity;\n\n // 3. PATCH\n const result = await fetch(`${apiBase}/api/v4/core/PRD/${productId}`, {\n method: 'PATCH',\n headers: {\n 'Authorization': `Bearer ${token}`,\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify({\n data: { XPRD09: newStock }\n })\n });\n\n return result.json();\n}\n\n// Usage\nawait incrementStock(123, 50); // Add 50 units\n"})}),"\n",(0,r.jsx)(n.h3,{id:"pattern-4-bulk-field-update",children:"Pattern 4: Bulk Field Update"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Update same field across multiple records:"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-javascript",children:"async function bulkUpdateCategory(productIds, newCategory) {\n const updates = productIds.map(id =>\n fetch(`${apiBase}/api/v4/core/PRD/${id}`, {\n method: 'PATCH',\n headers: {\n 'Authorization': `Bearer ${token}`,\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify({\n data: { XPRD05: newCategory }\n })\n })\n );\n\n return Promise.all(updates);\n}\n\n// Usage\nawait bulkUpdateCategory([123, 124, 125], 'cat_new_electronics');\n"})}),"\n",(0,r.jsx)(n.h2,{id:"javascript-implementation",children:"JavaScript Implementation"}),"\n",(0,r.jsx)(n.h3,{id:"product-service-with-patch",children:"Product Service with PATCH"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-javascript",children:"class ProductService {\n constructor(apiBase, token) {\n this.apiBase = apiBase;\n this.token = token;\n }\n\n /**\n * Partial update (PATCH)\n */\n async patchProduct(productId, changes) {\n const response = await fetch(`${this.apiBase}/api/v4/core/PRD/${productId}`, {\n method: 'PATCH',\n headers: {\n 'Authorization': `Bearer ${this.token}`,\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify({ data: changes })\n });\n\n if (!response.ok) {\n const error = await response.json();\n throw new ProductUpdateError(error);\n }\n\n return response.json();\n }\n\n /**\n * Update price\n */\n async updatePrice(productId, newPrice) {\n return this.patchProduct(productId, { XPRD02: newPrice });\n }\n\n /**\n * Update stock\n */\n async updateStock(productId, newStock) {\n return this.patchProduct(productId, { XPRD09: newStock });\n }\n\n /**\n * Set active status\n */\n async setActive(productId, active) {\n return this.patchProduct(productId, { XPRD06: active });\n }\n\n /**\n * Update category\n */\n async updateCategory(productId, categoryId) {\n return this.patchProduct(productId, { XPRD05: categoryId });\n }\n}
1\n\nclass ProductUpdateError extends Error {\n constructor(errorResponse) {\n super(errorResponse.message);\n this.code = errorResponse.code;\n this.field = errorResponse.field;\n }\n}\n\n// Usage\nconst productService = new ProductService(apiBase, token);\n\n// Update price\nawait productService.updatePrice(123, 89.99);\n\n// Set inactive\nawait productService.setActive(123, false);\n\n// Update category\nawait productService.updateCategory(123, 'cat_new_electronics');\n"})}),"\n",(0,r.jsx)(n.h3,{id:"react-hook-for-patch",children:"React Hook for PATCH"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-javascript",children:"import { useState } from 'react';\n\nfunction useProductPatch(apiBase, token) {\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState(null);\n\n async function patchProduct(productId, changes) {\n setLoading(true);\n setError(null);\n\n try {\n const response = await fetch(`${apiBase}/api/v4/core/PRD/${productId}`, {\n method: 'PATCH',\n headers: {\n 'Authorization': `Bearer ${token}`,\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify({ data: changes })\n });\n\n if (!response.ok) {\n const errorData = await response.json();\n throw new Error(errorData.message);\n }\n\n const result = await response.json();\n return result;\n } catch (err) {\n setError(err.message);\n throw err;\n } finally {\n setLoading(false);\n }\n }\n\n return { patchProduct, loading, error };\n}\n\n// Usage in component\nfunction ProductPriceEditor({ productId }) {\n const { patchProduct, loading, error } = useProductPatch(apiBase, token);\n const [price, setPrice] = useState('');\n\n async function handleSave() {\n try {\n await patchProduct(productId, { XPRD02: parseFloat(price) });\n alert('Price updated!');\n } catch (err) {\n alert(`Error: ${err.message}`);\n }\n }\n\n return (\n <div>\n <input\n type=\"number\"\n value={price}\n onChange={(e) => setPrice(e.target.value)}\n disabled={loading}\n />\n <button onClick={handleSave} disabled={loading}>\n {loading ? 'Saving...' : 'Save'}\n </button>\n {error && <div className=\"error\">{error}</div>}\n </div>\n );\n}\n"})}),"\n",(0,r.jsx)(n.h2,{id:"cod_on_off-validation",children:"COD_ON_OFF Validation"}),"\n",(0,r.jsx)(n.h3,{id:"modifiable-fields",children:"Modifiable Fields"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"TB_COST.COD_ON_OFF must include 'M' flag:"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sql",children:"-- XPRD02 can be patched (M flag present)\nINSERT INTO TB_COST (COD_DIM, NUM_COST, COD_VAR, COD_ON_OFF) VALUES\n('PRD', 2, 'XPRD02', 'LDNMR');\n\n-- XPRD03 cannot be patched (M flag missing)\nINSERT INTO TB_COST (COD_DIM, NUM_COST, COD_VAR, COD_ON_OFF) VALUES\n('PRD', 3, 'XPRD03', 'LDR'); -- Read-only counter\n"})}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Validation Error:"})}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Request:"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:'PATCH /api/v4/core/PRD/123\n{\n "data": {\n "XPRD03": "PRD-2025-999" // Read-only field\n }\n}\n'})}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Response:"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-json",children:'{\n "error": "ValidationError",\n "message": "Field not modifiable: XPRD03",\n "code": "FIELD_NOT_MODIFIABLE",\n "field": "XPRD03",\n "dimension": "PRD"\n}\n'})}),"\n",(0,r.jsx)(n.h2,{id:"patch-with-update_cascade",children:"PATCH with UPDATE_CASCADE"}),"\n",(0,r.jsx)(n.h3,{id:"cascading-updates",children:"Cascading Updates"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"TB_COST.UPDATE_CASCADE triggers related updates:"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sql",children:"-- When product name changes, update order items\nINSERT INTO TB_COST (COD_DIM, NUM_COST, COD_VAR, UPDATE_CASCADE) VALUES\n('PRD', 1, 'XPRD01', 'ORDITEM:XORDITEM_PRODUCT_NAME');\n"})}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"PATCH Triggers Cascade:"})}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Request:"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:'PATCH /api/v4/core/PRD/123\n{\n "data": {\n "XPRD01": "Widget Pro V2" // Name changed\n }\n}\n'})}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Result:"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sql",children:"-- Updates product\nUPDATE TB_ANAG_PRD00\nSET XPRD01 = 'Widget Pro V2', TREC = 'M', LDATA = '20251219160000'\nWHERE PRD_ID = 123;\n\n-- Cascades to order items\nUPDATE TB_ANAG_ORDITEM00\nSET XORDITEM_PRODUCT_NAME = 'Widget Pro V2', TREC = 'M', LDATA = '20251219160000'\nWHERE XORDITEM10 = 123;\n"})}),"\n",(0,r.jsx)(n.h2,{id:"best-practices",children:"Best Practices"}),"\n",(0,r.jsx)(n.h3,{id:"-do",children:"\u2705 DO:"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Use PATCH for single field updates:"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-javascript",children:'// \u2705 Good - update only price\nPATCH /api/v4/core/PRD/123\n{ "data": { "XPRD02": 89.99 } }\n'})}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Use PATCH for multiple field updates:"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-javascript",children:'// \u2705 Good - update multiple fields\nPATCH /api/v4/core/PRD/123\n{\n "data": {\n "XPRD02": 89.99,\n "XPRD06": false,\n "XPRD09": 0\n }\n}\n'})}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Handle validation errors:"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-javascript",children:"// \u2705 Good\ntry {\n await patchProduct(123, { XPRD02: 89.99 });\n} catch (error) {\n if (error.code === 'FIELD_NOT_MODIFIABLE') {\n alert(`Field ${error.field} is read-only`);\n }\n}\n"})}),"\n",(0,r.jsx)(n.h3,{id:"-dont",children:"\u274c DON'T:"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Don't use PUT when PATCH is sufficient:"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-javascript",children:'// \u274c Bad - PUT for single field\nPUT /api/v4/core/PRD/123\n{\n "data": {\n "XPRD01": "...",\n "XPRD02": 89.99, // Only changing this\n "XPRD04": "...",\n // ... all other fields\n }\n}\n\n// \u2705 Good - PATCH\nPATCH /api/v4/core/PRD/123\n{ "data": { "XPRD02": 89.99 } }\n'})}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Don't include unchanged fields:"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-javascript",children:'// \u274c Bad - unnecessary fields\nPATCH /api/v4/core/PRD/123\n{\n "data": {\n "XPRD01": "Widget Pro", // Unchanged\n "XPRD02": 89.99, // Changed\n "XPRD04": "Description" // Unchanged\n }\n}\n\n// \u2705 Good - only changed field\nPATCH /api/v4/core/PRD/123\n{ "data": { "XPRD02": 89.99 } }\n'})}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Don't try to PATCH read-only fields:"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-javascript",children:'// \u274c Bad - counter is read-only\nPATCH /api/v4/core/PRD/123\n{ "data": { "XPRD03": "PRD-2025-999" } }\n'})}),"\n",(0,r.jsx)(n.h2,{id:"performance-considerations",children:"Performance Considerations"}),"\n",(0,r.jsx)(n.h3,{id:"patch-vs-put-performance",children:"PATCH vs PUT Performance"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"PATCH advantages:"})}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Smaller request payload"}),"\n",(0,r.jsx)(n.li,{children:"No need to fetch current record"}),"\n",(0,r.jsx)(n.li,{children:"Fewer database columns updated"}),"\n",(0,r.jsx)(n.li,{children:"Faster execution"}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Benchmark:"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"PUT with 20 fields: ~50ms (fetch + update)\nPATCH with 1 field: ~10ms (update only)\n\n5x faster with PATCH\n"})}),"\n",(0,r.jsx)(n.h2,{id:"conditional-updates",children:"Conditional Updates"}),"\n",(0,r.jsx)(n.h3,{id:"update-only-if-condition-met",children:"Update Only If Condition Met"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-javascript",children:"async function updatePriceIfActive(productId, newPrice) {\n // 1. Fetch current\n const response = await fetch(`${apiBase}/api/v4/core/PRD/${productId}`, {\n headers: { 'Authorization': `Bearer ${token}` }\n });\n const current = await response.json();\n\n // 2. Check condition\n if (!current.data.XPRD06) {\n throw new Error('Product is not active. Cannot update price.');\n }\n\n // 3. PATCH\n const result = await fetch(`${apiBase}/api/v4/core/PRD/${productId}`, {\n method: 'PATCH',\n headers: {\n 'Authorization': `Bearer ${token}`,\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify({\n data: { XPRD02: newPrice }\n })\n });\n\n return result.json();\n}\n"})}),"\n",(0,r.jsx)(n.h2,{id:"summary",children:"Summary"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"\u2705 PATCH updates ONLY specified fields"}),"\n",(0,r.jsx)(n.li,{children:"\u2705 Other fields remain unchanged (safer than PUT)"}),"\n",(0,r.jsx)(n.li,{children:"\u2705 No need to fetch record first (unlike PUT)"}),"\n",(0,r.jsx)(n.li,{children:"\u2705 Minimal request payload (better performance)"}),"\n",(0,r.jsx)(n.li,{children:"\u2705 Sets TREC='M' automatically"}),"\n",(0,r.jsx)(n.li,{children:"\u2705 COD_ON_OFF='M' flag required for modifiable fields"}),"\n",(0,r.jsx)(n.li,{children:"\u2705 UPDATE_CASCADE propagates changes to related records"}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Key Takeaways:"})}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsx)(n.li,{children:"Prefer PATCH over PUT for most updates"}),"\n",(0,r.jsx)(n.li,{children:"Only include fields that are changing"}),"\n",(0,r.jsx)(n.li,{children:"No need to fetch current record (unlike PUT)"}),"\n",(0,r.jsx)(n.li,{children:"5x faster than PUT for single field updates"}),"\n",(0,r.jsx)(n.li,{children:"Safer - no risk of data loss from omitted fields"}),"\n",(0,r.jsx)(n.li,{children:"TREC automatically transitions to 'M'"}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"When to use PATCH vs PUT:"})}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"PATCH:"}
1)," Single/few field updates (99% of cases)"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"PUT:"})," Full record replacement (rare - only when intentional)"]}),"\n"]}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.strong,{children:"Next:"})," ",(0,r.jsx)(n.a,{href:"/docs/products/map.q01.io/core-api-platform-v4/write-patterns/delete-operations",children:"Delete Operations \u2192"})]}),"\n",(0,r.jsx)(n.h2,{id:"related-concepts",children:"Related Concepts"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.a,{href:"/docs/products/map.q01.io/core-api-platform-v4/write-patterns/update-operations",children:"Update Operations"})," - PUT operations"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.a,{href:"/docs/products/map.q01.io/core-api-platform-v4/core-concepts/field-visibility",children:"Field Visibility"})," - COD_ON_OFF flags"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.a,{href:"/docs/products/map.q01.io/core-api-platform-v4/core-concepts/entity-lifecycle",children:"Entity Lifecycle"})," - TREC states"]}),"\n"]})]})}function p(e={}){const{wrapper:n}={...(0,a.M)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(o,{...e})}):o(e)}},2172:(e,n,t)=>{t.d(n,{I:()=>d,M:()=>s});var r=t(1504);const a={},i=r.createContext(a);function s(e){const n=r.useContext(i);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:s(e.components),r.createElement(i.Provider,{value:n},e.children)}}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.