HTTP Upserts refer to a combination of HTTP methods used to either update existing resources or create new ones if they do not already exist. This pattern is commonly implemented using the PUT or POST methods, depending on the specifics of the API design.

Details

In HTTP, the concept of “upsert” is not natively supported by a single method but can be accomplished using PUT or POST methods:

  • PUT: This method is idempotent and typically used for updating resources. When used for upserts, if the resource does not exist at the specified URL, it is created.
  • POST: Generally used to create new resources. For upsert operations, POST requests must be designed to check for the existence of the resource and then update it if it exists, otherwise create it.

The choice between PUT and POST for upsert operations depends on the API’s design principles, specifically how URLs and resource identifiers are managed.

Common Pattern Names/Synonyms

The HTTP Upserts pattern is also commonly referred to using the following synonyms:

  1. Create or Update
  2. Insert or Update
  3. PUT or POST Upserts
  4. Conditional PUT/POST
  5. Idempotent POST (when POST is designed to be idempotent like PUT)

These terms emphasize the dual functionality of this pattern—either creating a new resource or updating an existing one based on its presence.

Common Use Cases

  1. Database Records: Updating a user profile where the user ID is known. If the profile exists, it is updated; if not, a new profile is created using the given ID.
  2. Configuration Settings: Applying settings where if a configuration doesn’t exist, it is created with default values, and if it does, it is updated with new values.
  3. Inventory Management: Adding or updating inventory items where each item has a unique identifier. If an item exists with that identifier, its details are updated; otherwise, a new item is added.

Mermaid Sequence Diagrams

PUT Method for Upserts

sequenceDiagram
    participant Client
    participant Server
    Client->>Server: PUT /resource/{id}
    Note right of Server: Check if {id} exists
    alt Resource exists
        Server->>Client: 200 OK (Resource updated)
    else Resource does not exist
        Server->>Client: 201 Created (Resource created)
    end

POST Method for Upserts

sequenceDiagram
    participant Client
    participant Server
    Client->>Server: POST /resource-check-and-update
    Note right of Server: Check if resource exists based on payload
    alt Resource exists
        Server->>Client: 200 OK (Resource updated)
    else Resource does not exist
        Server->>Client: 201 Created (Resource created)
    end

Examples

PUT Upsert Example

Request:

PUT /users/12345
Content-Type: application/json

{
  "name": "John Doe",
  "email": "john.doe@example.com"
}

Response (if user 12345 exists):

200 OK
{
  "id": "12345",
  "name": "John Doe",
  "email": "john.doe@example.com"
}

Response (if user 12345 does not exist):

201 Created
{
  "id": "12345",
  "name": "John Doe",
  "email": "john.doe@example.com"
}

POST Upsert Example

Request:

POST /user-upsert
Content-Type: application/json

{
  "id": "12345",
  "name": "John Doe",
  "email": "john.doe@example.com"
}

Response (if user 12345 exists):

200 OK
{
  "id": "12345",
  "name": "John Doe",
  "email": "john.doe@example.com"
}

Response (if user 12345 does not exist):

201 Created
{
  "id": "12345",
  "name": "John Doe",
  "email": "john.doe@example.com"
}

Updated: