The Immutable Resource Pattern focuses on designing REST-based APIs for handling Create and Read operations only, simplifying scenarios where modification or deletion of resources is either not required or handled differently.
Details
The Create and Read-only pattern caters to use cases where resources need to be added and retrieved without the need for updates or deletions, such as logging events, read-only data views, or situations where data integrity must be preserved indefinitely. This pattern leverages HTTP POST for creating resources and GET for reading them, ensuring straightforward implementation and clear operational boundaries.
Common Pattern Names/Synonyms
- Partial CRUD Operations
- Create-Read (CR) Pattern
- Immutable CRUD Pattern
Common Use Cases
- Event Logging: Capturing events that should not be altered once recorded.
- Reporting Systems: Generating and retrieving reports where data should not be changed once created.
- Audit Trails: Creating and viewing audit records which are strictly read-only for security and compliance.
When to Use
- Immutable data requirements: Ideal for applications where data once written should not be altered or deleted.
- Simplicity in data handling: Useful for services where only addition and retrieval functionalities are needed, reducing the complexity of the API.
- Read-heavy applications: Best suited for scenarios where data is frequently read but rarely or never modified.
When Not to Use
- Full data lifecycle management required: Not suitable for applications that require updating or deleting resources.
- Flexible data management needs: Inefficient for scenarios where users expect to manage the full lifecycle of data.
Examples
Create a New Resource
Request:
POST /api/events HTTP/1.1
Host: example.com
Content-Type: application/json
{
"eventType": "login",
"timestamp": "2024-10-08T12:34:56Z",
"details": {
"userId": "12345",
"ipAddress": "192.168.1.100"
}
}
Response:
HTTP/1.1 201 Created
Location: /api/events/45678
Read an Existing Resource
Request:
GET /api/events/45678 HTTP/1.1
Host: example.com
Response:
HTTP/1.1 200 OK
Content-Type: application/json
{
"id": "45678",
"eventType": "login",
"timestamp": "2024-10-08T12:34:56Z",
"details": {
"userId": "12345",
"ipAddress": "192.168.1.100"
}
}
This Create and Read pattern addresses specific needs for maintaining and retrieving data without the complications of updating or deleting, providing a clean and focused API strategy particularly beneficial for data integrity and simplicity.
Sequence Diagram Example
sequenceDiagram
participant Client
participant Server
participant Database
Note over Client,Server: Create and Read (Immutable) Operations
Client->>Server: POST /events (Create Event)
Server->>Database: Insert Event Data
Database-->>Server: Confirmation
Server-->>Client: 201 Created (Location Header)
Client->>Server: GET /events/{eventId} (Read Event)
Server->>Database: Fetch Event Data
Database-->>Server: Event Data
Server-->>Client: 200 OK (Event Data)
OpenAPI Example
openapi: 3.0.0
info:
title: Create and Read API
version: 1.0.0
servers:
- url: 'https://api.example.com'
paths:
/events/{eventId}:
get:
summary: Retrieves an event
parameters:
- name: eventId
in: path
required: true
schema:
type: string
responses:
'200':
description: A single event
content:
application/json:
schema:
$ref: '#/components/schemas/Event'
examples:
eventExample:
value:
id: "45678"
eventType: "login"
timestamp: "2024-10-08T12:34:56Z"
details:
userId: "12345"
ipAddress: "192.168.1.100"
/events:
post:
summary: Creates an event
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/Event'
examples:
newEvent:
value:
eventType: "login"
timestamp: "2024-10-08T12:34:56Z"
details:
userId: "12345"
ipAddress: "192.168.1.100"
responses:
'201':
description: Event created
headers:
Location:
schema:
type: string
description: URI of the created event
components:
schemas:
Event:
type: object
required:
- eventType
- timestamp
properties:
id:
type: string
eventType:
type: string
timestamp:
type: string
details:
type: object
properties:
userId:
type: string
ipAddress:
type: string