Skip to main content

Overview

This endpoint updates an existing product with new information. It supports both PUT and PATCH methods, allowing for partial updates - only the fields provided in the request body will be updated. The operation is transactional and automatically updates the updatedAt timestamp.

Path Parameters

id
long
required
The unique identifier of the product to update

Request Body

All fields are optional for partial updates. Only include the fields you want to modify.
name
string
New product name (must not be blank if provided)
description
string
New product description (must not be blank if provided)
price
decimal
New product price (BigDecimal format, e.g., 39.99)
stockQuantity
long
New stock quantity (long integer)
categories
array
Additional categories to associate with the product. This will add to existing categories, not replace them.
id
long
Product-category association ID
category
object
Category object to add

Response

Returns the updated product entity with all current values.
id
long
Product ID (unchanged)
name
string
Updated or existing product name
description
string
Updated or existing description
price
decimal
Updated or existing price
stockQuantity
long
Updated or existing stock quantity
discount
decimal
Product discount (if applicable)
categories
array
Complete list of category associations
createdAt
datetime
Original creation timestamp (unchanged)
updatedAt
datetime
Automatically updated to the current timestamp

Status Codes

200
OK
Product updated successfully
404
Not Found
Product with the specified ID does not exist
400
Bad Request
Invalid request body or field values (e.g., blank name/description)
500
Internal Server Error
Server error occurred while updating the product

Examples

curl -X PATCH "http://localhost:8080/products/1" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{
    "price": 39.99
  }'

Request Body Example (Partial Update)

{
  "price": 39.99,
  "stockQuantity": 200
}

Request Body Example (Full Update)

{
  "name": "Premium Wireless Mouse",
  "description": "Enhanced ergonomic wireless mouse with RGB lighting, adjustable DPI up to 16000, and rechargeable battery",
  "price": 49.99,
  "stockQuantity": 200
}

Success Response Example (200 OK)

{
  "id": 1,
  "name": "Premium Wireless Mouse",
  "description": "Enhanced ergonomic wireless mouse with RGB lighting, adjustable DPI up to 16000, and rechargeable battery",
  "price": 49.99,
  "stockQuantity": 200,
  "discount": null,
  "categories": [
    {
      "id": 1,
      "product": null,
      "category": {
        "id": 1,
        "name": "Electronics"
      }
    },
    {
      "id": 5,
      "product": null,
      "category": {
        "id": 3,
        "name": "Computer Accessories"
      }
    }
  ],
  "user": null,
  "createdAt": "2026-01-15T10:30:00",
  "updatedAt": "2026-03-03T15:45:30"
}

Error Response Example (404 Not Found)

{
  "timestamp": "2026-03-03T15:45:30",
  "status": 404,
  "error": "Not Found",
  "message": "Could not find product 999",
  "path": "/products/999"
}

Error Response Example (400 Bad Request)

{
  "timestamp": "2026-03-03T15:45:30",
  "status": 400,
  "error": "Bad Request",
  "message": "Product name cannot be blank",
  "path": "/products/1"
}
Partial Updates: This endpoint implements smart partial updates. Only fields that are present and valid in the request body will be updated. Missing fields remain unchanged.
Automatic Timestamp: The updatedAt field is automatically set to the current timestamp whenever any field is successfully updated.
PUT vs PATCH: While both methods are supported, PATCH is semantically more correct for partial updates. The implementation treats both identically.
Category Behavior: The categories field uses additive behavior - new categories are added to existing ones rather than replacing them. To completely replace categories, you would need to delete and recreate the product.
Validation: Blank strings for name and description are rejected even if the field is provided. Either omit the field entirely or provide a valid non-blank value.

Build docs developers (and LLMs) love