Including a Client Reference ID in POST and PATCH Requests

Introduction

To ensure idempotency in non-idempotent operations such as POST and PATCH, we introduce the concept of a Client Reference ID. This unique identifier allows clients to retry requests without the risk of creating duplicate entries or performing unintended duplicate updates. This document explains why using a Client Reference ID is a best practice and provides instructions on how to utilize it in your requests.

Why Use a Client Reference ID?

Idempotence is the property of an operation where executing it multiple times does not change the result beyond the initial application. While GET, PUT, and DELETE operations are inherently idempotent, POST and PATCH operations are not. This can lead to issues such as duplicate entries or unintended updates if a request is retried due to network failures or timeouts.

By including a Client Reference ID with each POST and PATCH request, we can enforce uniqueness on the server side, ensuring that:

  • POST operations do not create duplicate resources.
  • PATCH operations do not apply the same update multiple times.

This mechanism provides exactly-once execution semantics, protecting against the Two Generals' Problem where the client is unsure if the operation was successful and may resend the request.

How to Utilize the Client Reference ID

1. Generating the Client Reference ID

The Client Reference ID should be a unique string generated by the client for each request. A common practice is to use a UUID (Universally Unique Identifier) which can be generated in most programming languages. Below are a few examples for generating UUIDs:

PHP

Here is how you can do it using the ramsey/uuid library, which is a popular package for generating UUIDs.

1. Install the ramsey/uuid library

First, you need to install the library using Composer:

composer require ramsey/uuid

2. Generate a Client Reference ID

Here is an example of generating a UUID in plain PHP:

require 'vendor/autoload.php';

use Ramsey\Uuid\Uuid;

$clientReferenceId = Uuid::uuid4()->toString();

echo $clientReferenceId;

This code will output a unique UUID every time it is run.

Python

In Python, you can use the built-in uuid module to generate a UUID.

Example

import uuid

client_reference_id = str(uuid.uuid4())

print(client_reference_id)

This will print a unique UUID each time the script is executed.

.NET

In .NET, you can use the Guid class to generate a UUID.

Example in C#

using System;
                    
public class Program
{
    public static void Main()
    {
        Guid clientReferenceId = Guid.NewGuid();
        Console.WriteLine(clientReferenceId.ToString());
    }
}

This will output a unique GUID each time the program is run.

2. Including the Client Reference ID in Requests

The Client Reference ID should be included in the request payload for POST and PATCH requests. Below are examples of how to structure your requests.

Example: POST Request

POST /api/group HTTP/1.1
Host: api.app.unifiedcompliance.com
Content-Type: application/json

{
    "clientReferenceId": "123e4567-e89b-12d3-a456-426614174000",
    "description": "Group Test 1"
}

Example: PATCH Request

PATCH /api/group/123 HTTP/1.1
Host: api.app.unifiedcompliance.com
Content-Type: application/json

{
    "clientReferenceId": "123e4567-e89b-12d3-a456-426614174000",
    "status": "Approved"
}