跳轉到

Anonymous Writes

There are scenarios where data needs to be written but not uniquely identified after the fact, such as entries in a log file or time series data points to be aggregated into statistics.

This pattern explores an alternative that aims to standardize how best to handle the type of non-resource-oriented data in our generally resource oriented APIs.

Implementation

API definition

abstract class ChatRoomApi {
  @post("/{parent=chatRooms/*}/statEntries:write")         
  WriteChatRoomStatEntry(req:
     WriteChatRoomStatEntryRequest): void;       
  @post("/{parent=chatRooms/*}/statEntries:batchWrite")    
  BatchWriteChatRoomStatEntry(req:
     BatchWriteChatRoomStatEntryRequest): void;  
}
interface ChatRoomStatEntry {       
  name: string;
  value: number | string | boolean | null;
}
interface WriteChatRoomStatEntryRequest {
  parent: string;
  entry: ChatRoomStatEntry;
}
interface BatchWriteChatRoomStatEntryRequest {
  parent: string;
  requests: WriteChatRoomStatEntryRequest[];
}

Exercises

  1. If we're worried about ingesting duplicate data via a write method, what's the best strategy to avoid this?
The request deduplication pattern should be a perfect fit to help avoid this problem.
  1. Why should a write method return no response body? Why is it a bad idea for a write method to return an LRO resource?
Unlike the standard create method that returns a newly created resource, the write method doesn’t exactly have a resource to return.
it’s often impossible to know when an individual piece of data becomes persisted as part of the aggregated statistical information.

This is primarily due to the fact that a single entry should contain no unique identifier, so there’s no way to track a single data point all the way through an analytics pipeline.

Even if we could track each data point through the system, one of the main points for relying on a write method rather than the standard create method was that we didn’t want to store all of the entries individually.

Instead we wanted to save space and compute time by aggregating data. If we then decide that each invocation of the write method should create a new Operation resource, we’ve basically shifted the problem from one place to another without really saving any space or energy.
  1. If we want to communicate that data was received but hasn't yet been processed, what options are available? Which is likely to be the best choice for most APIs?
A good alternative is to simply return an HTTP 202 Accepted response code rather than the typical HTTP 200 OK response code.

Summary

  • When data needs to be ingested into a system (e.g., analytical data entries), we should rely on a custom write method rather than creating resources that will never be addressed individually.

  • Data loaded into an API via a write method is a one-way street and cannot be later removed from the API.

  • Write methods (and their batch versions) should return no response other than the resulting status codes. They should not return a resource at all—even an LRO resource—except in special circumstances.

  • Rather than resources, the write method deals with entries, which are similar to resources but are not addressable and, in many cases, ephemeral.