682 lines
19 KiB
Markdown
682 lines
19 KiB
Markdown
# OData Operation Template
|
|
|
|
## How to Use This Template
|
|
|
|
**Purpose**: Document individual OData operations (CRUD, functions, actions) with complete request/response details.
|
|
|
|
**When to Use**:
|
|
- Creating detailed documentation for a specific OData operation
|
|
- Documenting CRUD operations with full request/response examples
|
|
- Documenting custom functions and actions
|
|
- Detailed operation documentation linked from Resource template
|
|
|
|
**Instructions**:
|
|
1. Replace all [bracketed text] with your actual operation information
|
|
2. Include complete, working HTTP request examples
|
|
3. Show real response examples with actual data and status codes
|
|
4. Document all possible status codes for this specific operation
|
|
5. Include both success and error response examples
|
|
6. Test the operation and verify all examples work
|
|
7. Remove optional sections if not applicable
|
|
|
|
**Cross-Reference**: Use with [OData Resource Template](#odata-resource-template) for resource context and [OData Service Overview Template](#odata-service-overview-template) for service-level info.
|
|
|
|
**Template Structure**:
|
|
- Title & Introduction
|
|
- Operation Details (type, HTTP method, permission)
|
|
- Request (headers, parameters, body, examples)
|
|
- Response (headers, status codes, body, examples)
|
|
|
|
---
|
|
|
|
## [Operation Name] ([HTTP Method])
|
|
|
|
[Provide comprehensive description of what this operation does. Include:
|
|
- What action is performed
|
|
- What is returned (if applicable)
|
|
- When to use this operation
|
|
- Important behaviors or side effects]
|
|
|
|
**Example**:
|
|
"Creates a new employee record in the system with provided information.
|
|
Automatically assigns unique employee ID and initializes default values
|
|
(status: ACTIVE, creation timestamp). Triggers HR workflow notifications."
|
|
|
|
---
|
|
|
|
## Usage
|
|
|
|
[Explain when and why to use this operation, including:
|
|
- Primary use cases and scenarios
|
|
- When to use alternative operations
|
|
- Important prerequisites or constraints
|
|
- Any special behaviors or workflows]
|
|
|
|
Use this operation to [describe scenario].
|
|
|
|
Key points:
|
|
- [Important characteristic or constraint]
|
|
- [Related operation if applicable]
|
|
- [Performance consideration if relevant]
|
|
- [Workflow impact or side effect if relevant]
|
|
|
|
**Example**:
|
|
"Use this operation when adding a new employee to the system. Required fields
|
|
include first name, last name, email, and department. Optional fields like
|
|
hire date and salary can be provided.
|
|
|
|
Key points:
|
|
- Automatically generates unique EmployeeID
|
|
- Email must be unique across system
|
|
- Returns created employee in response body (if Prefer header included)
|
|
- Triggers HR workflow notifications to department manager
|
|
- Related operations: PATCH for updates, GET for retrieval"
|
|
|
|
---
|
|
|
|
## Request
|
|
|
|
### Operation Details
|
|
|
|
**URI**: [HTTP Method] [Path]
|
|
|
|
**Example**: `POST /Employees`, `GET /Employees('E12345')`, `PATCH /Employees('E12345')`
|
|
|
|
**Operation Type**: [CRUD/Function/Action]
|
|
|
|
| Aspect | Value |
|
|
|---|---|
|
|
| HTTP Method | [GET/POST/PUT/PATCH/DELETE] |
|
|
| Operation Type | [CRUD (standard)/Function (returns data)/Action (performs action)] |
|
|
| Resource | [Resource name] |
|
|
| Full URI Pattern | [Complete URI pattern with placeholders] |
|
|
|
|
**Example**:
|
|
```
|
|
| Aspect | Value |
|
|
|---|---|
|
|
| HTTP Method | POST |
|
|
| Operation Type | CRUD (Create) |
|
|
| Resource | Employees |
|
|
| Full URI Pattern | POST /Employees |
|
|
```
|
|
|
|
### Required Permission
|
|
|
|
**Permission**: [Required role or permission level]
|
|
|
|
[Explanation of what this permission allows and why it's required]
|
|
|
|
**Example**:
|
|
"Permission: ROLE_HR_MANAGER or ROLE_ADMIN
|
|
|
|
Only users with ROLE_HR_MANAGER or higher role can create employees.
|
|
Lower roles like ROLE_HR_USER cannot call this operation."
|
|
|
|
### Request Headers
|
|
|
|
| Header Name | Required | Possible Values | Description |
|
|
|---|---|---|---|
|
|
| [Header] | [Yes/No] | [Values] | [Description with format/examples] |
|
|
|
|
**Example**:
|
|
```
|
|
| Header Name | Required | Possible Values | Description |
|
|
|---|---|---|---|
|
|
| Authorization | Yes | Bearer {token} | OAuth2 authentication token. Format: Bearer {token}. Required for all operations. |
|
|
| Content-Type | Yes (POST/PUT/PATCH) | application/json | Media type of request body. Required for operations with request body. Value: application/json |
|
|
| Accept | No | application/json | Preferred response format. Default: application/json. Optional: specify other formats if supported. |
|
|
| Prefer | No | return=representation, return=minimal | OData preference. return=representation: include created/updated entity in response. return=minimal: response without body (faster). |
|
|
| If-Match | No | {ETag} | ETag for optimistic concurrency control. Format: quoted string (e.g., "abc123"). Required for safe concurrent updates on PUT/PATCH. |
|
|
| X-Request-ID | No | UUID | Optional request tracking ID. Format: any valid UUID. Example: 123e4567-e89b-12d3-a456-426614174000 |
|
|
```
|
|
|
|
### Request Parameters
|
|
|
|
[Document all parameters passed to the operation, organized by location.]
|
|
|
|
#### Path Parameters
|
|
|
|
[If operation uses path parameters in URI]
|
|
|
|
| Parameter Name | Requirement | Data Type | Description | Location |
|
|
|---|---|---|---|---|
|
|
| [Name] | Required/Optional | [Type] | [Description with constraints, pattern, valid values] | Path |
|
|
|
|
**Example**:
|
|
```
|
|
| Parameter Name | Requirement | Data Type | Description | Location |
|
|
|---|---|---|---|---|
|
|
| EmployeeID | Required | String | Employee unique identifier. Pattern: E[0-9]{5}. Example: "E12345" | Path |
|
|
```
|
|
|
|
#### Query Parameters
|
|
|
|
[If operation uses query parameters]
|
|
|
|
| Parameter Name | Requirement | Data Type | Description | Location |
|
|
|---|---|---|---|---|
|
|
| $filter | Optional | String | OData filter expression for query. Example: FirstName eq 'John'. Used only in GET collection operations. | Query |
|
|
| $orderby | Optional | String | Sort order. Example: HireDate desc, LastName asc. Used in GET collection operations. | Query |
|
|
| $top | Optional | Integer | Maximum records to return (1-1000). Default: 50. Used for pagination. | Query |
|
|
| $skip | Optional | Integer | Records to skip for pagination. Default: 0. Used with $top. | Query |
|
|
| $select | Optional | String | Properties to include in response. Example: FirstName,LastName,Email. Reduces payload size. | Query |
|
|
| $expand | Optional | String | Navigate relationships and include related data. Example: Department,Manager. Limited to 3 levels deep. | Query |
|
|
|
|
**Detailed Example for POST**:
|
|
```
|
|
[No query parameters for POST operations - all data in request body]
|
|
```
|
|
|
|
**Detailed Example for GET with Collection**:
|
|
```
|
|
| Parameter Name | Requirement | Data Type | Description | Location |
|
|
|---|---|---|---|---|
|
|
| $filter | Optional | String | Filter expression. Example: $filter=Status eq 'ACTIVE' and Salary gt 100000 | Query |
|
|
| $orderby | Optional | String | Sort fields. Example: $orderby=HireDate desc,LastName asc | Query |
|
|
| $top | Optional | Integer | Max results (1-1000, default: 50). Example: $top=100 | Query |
|
|
| $skip | Optional | Integer | Records to skip for pagination. Example: $skip=200 | Query |
|
|
| $select | Optional | String | Properties to include. Example: $select=FirstName,LastName,Email | Query |
|
|
| $expand | Optional | String | Include related data. Example: $expand=Department,Manager | Query |
|
|
| $count | Optional | Boolean | Include total count. Returns entities with @odata.count. Value: true. Example: ?$count=true. Note: Path /Employees/$count returns only integer count. | Query |
|
|
```
|
|
|
|
#### Request Body
|
|
|
|
[For POST/PUT/PATCH operations with request body]
|
|
|
|
**Format**: [JSON structure with all properties]
|
|
|
|
**Required Fields**: [List of required fields]
|
|
|
|
**Optional Fields**: [List of optional fields]
|
|
|
|
| Property Name | Requirement | Data Type | Description | Constraints |
|
|
|---|---|---|---|---|
|
|
| [Property] | Required/Optional | [Type] | [Description] | [Min/max, format, valid values] |
|
|
|
|
**Example**:
|
|
```
|
|
Request body structure:
|
|
|
|
{
|
|
"FirstName": "string",
|
|
"LastName": "string",
|
|
"Email": "string",
|
|
"Department": "string",
|
|
"HireDate": "date",
|
|
"Salary": "decimal"
|
|
}
|
|
|
|
Required Fields: FirstName, LastName, Email, Department
|
|
|
|
Optional Fields: HireDate, Salary
|
|
|
|
| Property Name | Requirement | Data Type | Description | Constraints |
|
|
|---|---|---|---|---|
|
|
| FirstName | Required | String | Employee's first name | 1-50 characters, alphanumeric + spaces |
|
|
| LastName | Required | String | Employee's last name | 1-50 characters, alphanumeric + spaces |
|
|
| Email | Required | String | Corporate email address | Must be unique, valid email format (RFC 5322) |
|
|
| Department | Required | String | Department code | Valid: "SALES", "ENGINEERING", "FINANCE", "HR", "OPERATIONS" |
|
|
| HireDate | Optional | Date | Hire date in YYYY-MM-DD format | Cannot be future date, ISO 8601 format |
|
|
| Salary | Optional | Decimal | Annual salary in USD | Minimum: 20000, maximum: 10000000, 2 decimal places |
|
|
```
|
|
|
|
### Request Example
|
|
|
|
[Provide complete, working HTTP request with all headers and body.]
|
|
|
|
**Template**:
|
|
```http
|
|
[HTTP METHOD] [Path]?[Query Parameters] HTTP/1.1
|
|
Host: [Host]
|
|
Authorization: Bearer [token]
|
|
Content-Type: application/json
|
|
[Additional Headers]
|
|
|
|
[Request body if applicable]
|
|
```
|
|
|
|
#### Example - GET Collection with Filtering
|
|
|
|
```http
|
|
GET /Employees?$filter=Status eq 'ACTIVE' and Department eq 'ENGINEERING'&$orderby=LastName asc&$top=50&$skip=0 HTTP/1.1
|
|
Host: api.example.com
|
|
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
|
|
Accept: application/json
|
|
```
|
|
|
|
#### Example - GET Single Resource
|
|
|
|
```http
|
|
GET /Employees('E12345') HTTP/1.1
|
|
Host: api.example.com
|
|
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
|
|
Accept: application/json
|
|
```
|
|
|
|
#### Example - POST (Create)
|
|
|
|
```http
|
|
POST /Employees HTTP/1.1
|
|
Host: api.example.com
|
|
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
|
|
Content-Type: application/json
|
|
Prefer: return=representation
|
|
|
|
```
|
|
|
|
#### Example - PATCH (Update)
|
|
|
|
```http
|
|
PATCH /Employees('E12345') HTTP/1.1
|
|
Host: api.example.com
|
|
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
|
|
Content-Type: application/json
|
|
If-Match: "abc123def456"
|
|
|
|
```
|
|
|
|
#### Example - PUT (Replace)
|
|
|
|
```http
|
|
PUT /Employees('E12345') HTTP/1.1
|
|
Host: api.example.com
|
|
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
|
|
Content-Type: application/json
|
|
|
|
```
|
|
|
|
#### Example - DELETE
|
|
|
|
```http
|
|
DELETE /Employees('E12345') HTTP/1.1
|
|
Host: api.example.com
|
|
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
|
|
```
|
|
|
|
---
|
|
|
|
## Response
|
|
|
|
### Response Headers
|
|
|
|
| Header Name | Description | Possible Values |
|
|
|---|---|---|
|
|
| [Header] | [What this header contains] | [Example values] |
|
|
|
|
**Example**:
|
|
```
|
|
| Header Name | Description | Possible Values |
|
|
|---|---|---|
|
|
| Content-Type | Response body media type | application/json |
|
|
| Location | URL of created/modified resource | [https://api.example.com/odata/v4/Employees('E12346](https://api.example.com/odata/v4/Employees('E12346)') |
|
|
| ETag | Entity tag for caching and concurrency control | "abc123def456" |
|
|
| OData-Version | OData protocol version used | 4.0 |
|
|
| Preference-Applied | Which Prefer preference was applied | return=representation, return=minimal |
|
|
```
|
|
|
|
### Status Codes
|
|
|
|
| Status Code | Description | Conditions | Response Body |
|
|
|---|---|---|---|
|
|
| [Code] | [What status means] | [When this occurs] | [Type of response body] |
|
|
|
|
**Example for GET (200 OK)**:
|
|
```
|
|
| Status Code | Description | Conditions | Response Body |
|
|
|---|---|---|---|
|
|
| 200 OK | Request successful | Entity/collection retrieved | Entity or collection data |
|
|
| 401 Unauthorized | Authentication required | Missing/invalid token | Error object |
|
|
| 403 Forbidden | Insufficient permissions | User lacks required role | Error object |
|
|
| 404 Not Found | Resource doesn't exist | Invalid ID/key | Error object |
|
|
| 500 Internal Server Error | Server error | Unhandled exception | Error object |
|
|
```
|
|
|
|
**Example for POST (201 Created)**:
|
|
```
|
|
| Status Code | Description | Conditions | Response Body |
|
|
|---|---|---|---|
|
|
| 201 Created | Resource created successfully | Valid request, auto-generated ID | Created entity (if Prefer: return=representation) |
|
|
| 400 Bad Request | Validation error | Invalid data, missing required field | Error object with details |
|
|
| 401 Unauthorized | Authentication required | Missing/invalid token | Error object |
|
|
| 403 Forbidden | Insufficient permissions | User lacks ROLE_HR_MANAGER | Error object |
|
|
| 409 Conflict | Duplicate/constraint violation | Email already exists | Error object with details |
|
|
| 500 Internal Server Error | Server error | Database error | Error object |
|
|
```
|
|
|
|
**Example for PATCH (204 No Content or 200 OK)**:
|
|
```
|
|
| Status Code | Description | Conditions | Response Body |
|
|
|---|---|---|---|
|
|
| 204 No Content | Update successful | Default response without Prefer header | Empty body |
|
|
| 200 OK | Update successful | Prefer: return=representation | Updated entity data |
|
|
| 400 Bad Request | Validation error | Invalid field values | Error object |
|
|
| 401 Unauthorized | Authentication required | Missing/invalid token | Error object |
|
|
| 403 Forbidden | Insufficient permissions | User lacks required role | Error object |
|
|
| 404 Not Found | Resource doesn't exist | Invalid ID | Error object |
|
|
| 412 Precondition Failed | Optimistic concurrency failure | If-Match ETag mismatch | Error object |
|
|
| 500 Internal Server Error | Server error | Database error | Error object |
|
|
```
|
|
|
|
### Response Body (Successful)
|
|
|
|
[Document the successful response body structure, including all properties.]
|
|
|
|
```json
|
|
{
|
|
"[property]": "[value or type]",
|
|
"[property]": "[value or type]"
|
|
}
|
|
```
|
|
|
|
**Example for GET Single (200 OK)**:
|
|
```json
|
|
{
|
|
"EmployeeID": "E12345",
|
|
"FirstName": "John",
|
|
"LastName": "Doe",
|
|
"Email": "john.doe@company.com",
|
|
"Department": "ENGINEERING",
|
|
"HireDate": "2020-06-01",
|
|
"Salary": 120000.00,
|
|
"Status": "ACTIVE",
|
|
"CreatedAt": "2020-06-01T09:00:00Z",
|
|
"LastModified": "2024-01-15T14:30:00Z"
|
|
}
|
|
```
|
|
|
|
**Example for GET Collection (200 OK)**:
|
|
```json
|
|
{
|
|
"value": [
|
|
{
|
|
"EmployeeID": "E12345",
|
|
"FirstName": "John",
|
|
"LastName": "Doe",
|
|
"Email": "john.doe@company.com",
|
|
"Status": "ACTIVE"
|
|
},
|
|
{
|
|
"EmployeeID": "E12346",
|
|
"FirstName": "Jane",
|
|
"LastName": "Smith",
|
|
"Email": "jane.smith@company.com",
|
|
"Status": "ACTIVE"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
**Example for POST (201 Created)**:
|
|
```json
|
|
{
|
|
"EmployeeID": "E12346",
|
|
"FirstName": "John",
|
|
"LastName": "Doe",
|
|
"Email": "john.doe@company.com",
|
|
"Department": "ENGINEERING",
|
|
"HireDate": "2024-01-15",
|
|
"Salary": 95000.00,
|
|
"Status": "ACTIVE",
|
|
"CreatedAt": "2024-01-15T10:30:00Z",
|
|
"LastModified": "2024-01-15T10:30:00Z"
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Complete Response Examples
|
|
|
|
### Success Response (200 OK - GET)
|
|
|
|
```http
|
|
HTTP/1.1 200 OK
|
|
Content-Type: application/json
|
|
ETag: "abc123def456"
|
|
OData-Version: 4.0
|
|
|
|
```
|
|
|
|
### Success Response (201 Created - POST)
|
|
|
|
```http
|
|
HTTP/1.1 201 Created
|
|
Content-Type: application/json
|
|
Location: [https://api.example.com/odata/v4/Employees('E12346](https://api.example.com/odata/v4/Employees('E12346)')
|
|
ETag: "def789ghi123"
|
|
OData-Version: 4.0
|
|
|
|
```
|
|
|
|
### Success Response (204 No Content - PATCH)
|
|
|
|
```http
|
|
HTTP/1.1 204 No Content
|
|
```
|
|
|
|
### Success Response (Collection - GET with $top/$skip)
|
|
|
|
```http
|
|
HTTP/1.1 200 OK
|
|
Content-Type: application/json
|
|
OData-Version: 4.0
|
|
|
|
```
|
|
|
|
---
|
|
|
|
## Error Response Examples
|
|
|
|
### Error Response (400 Bad Request)
|
|
|
|
```http
|
|
HTTP/1.1 400 Bad Request
|
|
Content-Type: application/json
|
|
|
|
```
|
|
|
|
### Error Response (401 Unauthorized)
|
|
|
|
```http
|
|
HTTP/1.1 401 Unauthorized
|
|
Content-Type: application/json
|
|
|
|
```
|
|
|
|
### Error Response (403 Forbidden)
|
|
|
|
```http
|
|
HTTP/1.1 403 Forbidden
|
|
Content-Type: application/json
|
|
|
|
```
|
|
|
|
### Error Response (404 Not Found)
|
|
|
|
```http
|
|
HTTP/1.1 404 Not Found
|
|
Content-Type: application/json
|
|
|
|
```
|
|
|
|
### Error Response (409 Conflict - Duplicate)
|
|
|
|
```http
|
|
HTTP/1.1 409 Conflict
|
|
Content-Type: application/json
|
|
|
|
```
|
|
|
|
### Error Response (500 Internal Server Error)
|
|
|
|
```http
|
|
HTTP/1.1 500 Internal Server Error
|
|
Content-Type: application/json
|
|
|
|
```
|
|
|
|
---
|
|
|
|
## Special Cases / Additional Notes
|
|
|
|
[Document any special behaviors, edge cases, or implementation notes]
|
|
|
|
**Example**:
|
|
- Soft delete: Employee records are marked with Status='TERMINATED', not physically deleted
|
|
- Automatic fields: EmployeeID, CreatedAt, and LastModified are auto-generated
|
|
- Optimistic concurrency: Use If-Match header with ETag to prevent lost updates
|
|
- Batch operations: This operation can be included in a $batch request
|
|
- Rate limiting: This operation counts as 1 request toward rate limit
|
|
|
|
---
|
|
|
|
## Related Operations
|
|
|
|
- [Resource Overview](#odata-resource-[name])
|
|
- [Service Overview](#odata-service-[name])
|
|
- [Related Operation 1](#odata-operation-[name])
|
|
- [Related Operation 2](#odata-operation-[name])
|
|
|
|
---
|
|
|
|
**Template Version**: 1.0
|
|
**Last Updated**: 2025-11-21
|
|
**Compliance**: SAP API Style Guide Section 50
|