Appearance
Delete Single Object
Delete a specific device (object) from the database, identified by UID, OID, or related OID. This endpoint allows selective deletion of individual objects rather than deleting all objects at once.
Request
http
DELETE /api/objectAuthentication Required: Must include JWT token in Authorization header.
Required Scope: objects
Query Parameters:
uid(string, optional): UID of the device to delete (hex format)oid(string, optional): OID of the device to delete (hex format)related_oid(string, optional): Related OID for deletion (hex format)
Parameter Logic:
- UID Priority: When
uidis provided,oidis ignored (UID takes precedence) - OID Fallback:
oidis only used whenuidis empty/not provided - Related Object Deletion:
related_oidworks with whichever identifier is active:uid+related_oid→ Deletes related object from the UID deviceoid+related_oid→ Deletes related object from the OID device (only ifuidis empty)
- At least one of
uidoroidmust be provided
Request Examples
Delete by UID
bash
curl -X DELETE "http://your-server-ip:port/api/object?uid=ABCDEF123456" \
-H "Authorization: Bearer YOUR_JWT_TOKEN"Delete by OID
bash
curl -X DELETE "http://your-server-ip:port/api/object?oid=1234567890" \
-H "Authorization: Bearer YOUR_JWT_TOKEN"Delete by UID (OID Ignored)
bash
# When both uid and oid are provided, only uid is used (oid is ignored)
curl -X DELETE "http://your-server-ip:port/api/object?uid=ABCDEF123456&oid=1234567890" \
-H "Authorization: Bearer YOUR_JWT_TOKEN"
# This will delete by UID ABCDEF123456 onlyDelete Related Object by UID
bash
curl -X DELETE "http://your-server-ip:port/api/object?uid=ABCDEF123456&related_oid=9876543210" \
-H "Authorization: Bearer YOUR_JWT_TOKEN"Delete Related Object by OID (when UID is empty)
bash
curl -X DELETE "http://your-server-ip:port/api/object?oid=1234567890&related_oid=9876543210" \
-H "Authorization: Bearer YOUR_JWT_TOKEN"Response
Success (200 OK)
json
{
"success": true
}Error Responses
All error responses are returned as JSON:
400 Bad Request
json
{
"error": "uid and/or oid must not be empty"
}json
{
"error": "Invalid uid"
}json
{
"error": "Invalid oid"
}json
{
"error": "Invalid related_oid"
}401 Unauthorized
json
{
"error": "NOT_LOGGED_IN"
}403 Forbidden
json
{
"error": "FORBIDDEN"
}405 Method Not Allowed
json
{
"error": "Method Not Allowed"
}500 Internal Server Error
json
{
"error": "Failed to delete object: Database error occurred"
}503 Service Unavailable
json
{
"error": "Database is not ready"
}Related Object Deletion
Parameter Precedence and Related Objects
Parameter Priority Rules:
- UID Priority: When
uidis provided,oidis completely ignored - OID Fallback:
oidis only used whenuidis empty or not provided - Related Object Logic:
related_oidworks with the active identifier
Deletion Behavior:
uid=ABC123→ Deletes entire device ABC123 (oid ignored if present)oid=123456(no uid) → Deletes entire device with OID 123456uid=ABC123&oid=999&related_oid=XYZ789→ Deletes only related object XYZ789 from device ABC123 (oid 999 is ignored)oid=123456&related_oid=XYZ789(no uid) → Deletes only related object XYZ789 from device with OID 123456
Important Notes:
- When
related_oidis used, only the related object is deleted, not the main device - The main device (identified by UID or OID) remains in the system
- This is useful for managing device components, sensors, or modules independently
Usage Examples
Basic Object Deletion
javascript
async function deleteObject(uid = null, oid = null, relatedOid = null) {
// Build query parameters
const params = new URLSearchParams();
if (uid) params.append('uid', uid);
if (oid) params.append('oid', oid);
if (relatedOid) params.append('related_oid', relatedOid);
if (params.toString() === '' && !relatedOid) {
throw new Error('At least one of uid or oid must be provided');
}
try {
const response = await fetch(`/api/object?${params.toString()}`, {
method: 'DELETE',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
}
});
if (!response.ok) {
const error = await response.json();
throw new Error(`HTTP ${response.status}: ${error.error}`);
}
const result = await response.json();
console.log('Object deleted successfully');
return result;
} catch (error) {
console.error('Failed to delete object:', error);
throw error;
}
}Object Management Class
javascript
class ObjectManager {
constructor(token) {
this.token = token;
}
async deleteByUid(uid) {
return await this.deleteObject({ uid });
}
async deleteByOid(oid) {
return await this.deleteObject({ oid });
}
async deleteByBoth(uid, oid) {
// Note: When both are provided, UID takes precedence (OID is ignored)
console.log(`Deleting by UID: ${uid} (OID ${oid} will be ignored)`);
return await this.deleteObject({ uid, oid });
}
async deleteRelatedObjectByUid(parentUid, relatedOid) {
console.log(`Deleting related object ${relatedOid} from device UID ${parentUid}`);
return await this.deleteObject({ uid: parentUid, relatedOid });
}
async deleteRelatedObjectByOid(parentOid, relatedOid) {
console.log(`Deleting related object ${relatedOid} from device OID ${parentOid}`);
return await this.deleteObject({ oid: parentOid, relatedOid });
}
async deleteRelatedObject(parentUid, relatedOid) {
// Legacy method - defaults to UID-based deletion
return await this.deleteRelatedObjectByUid(parentUid, relatedOid);
}
async deleteObject({ uid = null, oid = null, relatedOid = null }) {
const params = new URLSearchParams();
if (uid) params.append('uid', uid);
if (oid) params.append('oid', oid);
if (relatedOid) params.append('related_oid', relatedOid);
const response = await fetch(`/api/object?${params.toString()}`, {
method: 'DELETE',
headers: {
'Authorization': `Bearer ${this.token}`,
'Content-Type': 'application/json'
}
});
if (!response.ok) {
const error = await response.json();
throw new Error(`Deletion failed: ${error.error}`);
}
return await response.json();
}
}
// Usage
const objectManager = new ObjectManager(authToken);
// Delete entire device
await objectManager.deleteByUid('ABC123');
// Delete device by OID (only when UID is not provided)
await objectManager.deleteByOid('1234567890');
// Delete only a related object by UID
await objectManager.deleteRelatedObjectByUid('ABC123', 'SENSOR001');
// Delete only a related object by OID (when UID is not available)
await objectManager.deleteRelatedObjectByOid('1234567890', 'SENSOR001');Batch Deletion with Confirmation
javascript
class BatchObjectDeletion {
constructor(token) {
this.token = token;
this.objectManager = new ObjectManager(token);
}
async deleteMultipleObjects(objects, confirmCallback = null) {
const results = [];
for (const obj of objects) {
try {
// Optional confirmation for each deletion
if (confirmCallback && !await confirmCallback(obj)) {
results.push({
object: obj,
status: 'skipped',
reason: 'User cancelled'
});
continue;
}
const result = await this.objectManager.deleteObject(obj);
results.push({
object: obj,
status: 'success',
result: result
});
console.log(`✓ Deleted object: ${obj.uid || obj.oid}`);
} catch (error) {
results.push({
object: obj,
status: 'error',
error: error.message
});
console.error(`✗ Failed to delete object: ${obj.uid || obj.oid} - ${error.message}`);
}
}
return results;
}
async deleteObjectsByFilter(objects, filterFn) {
const objectsToDelete = objects.filter(filterFn);
return await this.deleteMultipleObjects(objectsToDelete);
}
}
// Usage
const batchDeletion = new BatchObjectDeletion(authToken);
// Delete multiple objects with confirmation
const objectsToDelete = [
{ uid: 'ABC123' },
{ oid: '1234567890' },
{ uid: 'DEF456', relatedOid: 'SENSOR001' }
];
const confirmDeletion = async (obj) => {
return confirm(`Delete object ${obj.uid || obj.oid}?`);
};
const results = await batchDeletion.deleteMultipleObjects(objectsToDelete, confirmDeletion);Error Handling and Validation
javascript
class ObjectDeletionValidator {
static validateUid(uid) {
if (!uid) return true; // Optional parameter
// Check hex format
if (!/^[0-9A-Fa-f]+$/.test(uid)) {
throw new Error('UID must be in hexadecimal format');
}
// Check length (adjust based on your system requirements)
if (uid.length < 6 || uid.length > 16) {
throw new Error('UID length must be between 6 and 16 characters');
}
return true;
}
static validateOid(oid) {
if (!oid) return true; // Optional parameter
// Check if numeric string
if (!/^\d+$/.test(oid)) {
throw new Error('OID must be numeric');
}
// Check reasonable range
const numericOid = parseInt(oid);
if (numericOid <= 0 || numericOid > 9999999999) {
throw new Error('OID must be between 1 and 9999999999');
}
return true;
}
static validateParameters(uid, oid, relatedOid) {
// At least one of uid or oid required
if (!uid && !oid) {
throw new Error('At least one of uid or oid must be provided');
}
// Warn if both UID and OID provided (OID will be ignored)
if (uid && oid) {
console.warn('Both UID and OID provided - OID will be ignored, using UID only');
}
this.validateUid(uid);
this.validateOid(oid);
this.validateOid(relatedOid); // Same format as OID
return true;
}
}
// Usage with validation
async function safeDeleteObject(uid, oid, relatedOid) {
try {
// Validate parameters
ObjectDeletionValidator.validateParameters(uid, oid, relatedOid);
// Proceed with deletion
return await deleteObject(uid, oid, relatedOid);
} catch (error) {
console.error('Validation failed:', error.message);
throw error;
}
}Related Object Management
javascript
class RelatedObjectManager {
constructor(token) {
this.token = token;
this.objectManager = new ObjectManager(token);
}
async removeDeviceComponent(deviceUid, componentType, componentId) {
const relatedOid = `${componentType}_${componentId}`;
try {
console.log(`Removing ${componentType} ${componentId} from device ${deviceUid}`);
const result = await this.objectManager.deleteRelatedObject(deviceUid, relatedOid);
console.log(`✓ Successfully removed ${componentType} from device ${deviceUid}`);
return result;
} catch (error) {
console.error(`✗ Failed to remove ${componentType} from device ${deviceUid}:`, error.message);
throw error;
}
}
async removeSensor(deviceUid, sensorId) {
return await this.removeDeviceComponent(deviceUid, 'SENSOR', sensorId);
}
async removeModule(deviceUid, moduleId) {
return await this.removeDeviceComponent(deviceUid, 'MODULE', moduleId);
}
async removeAllComponents(deviceUid, components) {
const results = [];
for (const component of components) {
try {
const result = await this.removeDeviceComponent(
deviceUid,
component.type,
component.id
);
results.push({ component, status: 'success', result });
} catch (error) {
results.push({ component, status: 'error', error: error.message });
}
}
return results;
}
}
// Usage
const relatedManager = new RelatedObjectManager(authToken);
// Remove specific components
await relatedManager.removeSensor('ABC123', 'TEMP001');
await relatedManager.removeModule('ABC123', 'COMM001');
// Remove multiple components
const components = [
{ type: 'SENSOR', id: 'TEMP001' },
{ type: 'SENSOR', id: 'HUM001' },
{ type: 'MODULE', id: 'GPS001' }
];
const results = await relatedManager.removeAllComponents('ABC123', components);Security Considerations
Deletion Confirmation
javascript
async function confirmAndDelete(uid, oid, relatedOid) {
let message;
if (relatedOid) {
message = `Delete related object ${relatedOid} from device ${uid || oid}?`;
} else {
message = `Delete entire device ${uid || oid}? This action cannot be undone.`;
}
if (!confirm(message)) {
console.log('Deletion cancelled by user');
return false;
}
return await deleteObject(uid, oid, relatedOid);
}Audit Logging
javascript
class DeletionAuditLogger {
static async logDeletion(uid, oid, relatedOid, success, error = null) {
const logEntry = {
timestamp: new Date().toISOString(),
action: 'object_deletion',
target: {
uid: uid || null,
oid: oid || null,
related_oid: relatedOid || null
},
success: success,
error: error,
user: this.getCurrentUser()
};
console.log('DELETION_AUDIT:', JSON.stringify(logEntry));
// Send to audit service
try {
await fetch('/api/audit/log', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(logEntry)
});
} catch (auditError) {
console.error('Failed to log audit entry:', auditError);
}
}
static getCurrentUser() {
try {
const token = localStorage.getItem('authToken');
const payload = JSON.parse(atob(token.split('.')[1]));
return payload.username || payload.sub;
} catch {
return 'unknown';
}
}
}
// Usage with audit logging
async function auditedDeleteObject(uid, oid, relatedOid) {
try {
const result = await deleteObject(uid, oid, relatedOid);
await DeletionAuditLogger.logDeletion(uid, oid, relatedOid, true);
return result;
} catch (error) {
await DeletionAuditLogger.logDeletion(uid, oid, relatedOid, false, error.message);
throw error;
}
}Important Notes
- Scope Required: Users must have the
objectsscope to access this endpoint - Selective Deletion: Unlike
/api/objects(DELETE all), this endpoint targets specific objects - Related Objects: Using
related_oiddeletes only the related object, not the main device - Parameter Validation: UID must be hex format, OID must be numeric
- JSON Errors: All error responses are in JSON format (unlike some other endpoints)