Expand description
Remove metakey
- Proposal Name:
remove_metakey - Start Date: 2024-11-12
- RFC PR: apache/opendal#5313
- Tracking Issue: apache/opendal#5314
§Summary
Remove the Metakey concept from OpenDAL and replace it with a simpler and more predictable metadata handling mechanism.
§Motivation
The current Metakey design has several issues:
- Performance Impact: Users often initiate costly operations unintentionally, such as using
Metakey::Full, which results in extra stat calls - Usability Issues: Users often try to access metadata that hasn’t been explicitly requested
- API Confusion: There’s a conflict between
Metakey::Versionand the newversion(bool)parameter - Implementation Complexity: Service developers struggle to implement
Metakeycorrectly
The goal is a simpler, more intuitive API that prevents common mistakes and improves performance as standard.
§Guide-level explanation
Instead of using Metakey to specify which metadata fields to fetch, services will now declare their metadata capabilities upfront through a new MetadataCapability struct:
let entries = op.list("path").await?;
for entry in entries {
if op.metadata_capability().content_type {
println!("Content-Type: {}", entry.metadata().content_type());
}
}If users need additional metadata not provided by list:
let entries = op.list("path").await?;
for entry in entries {
let mut meta = entry.metadata();
if !op.metadata_capability().etag {
meta = op.stat(&entry.path()).await?;
}
println!("Content-Type: {}", meta.etag());
}For existing OpenDAL users, the main changes are:
- Remove all
metakey()calls from their code - Use
metadata_capability()to check available metadata - Explicitly call
stat()when needed
§Reference-level explanation
The implementation involves:
- Remove the
Metakeyenum - Add new
MetadataCapabilitystruct:
pub struct MetadataCapability {
pub content_length: bool,
pub content_type: bool,
pub last_modified: bool,
pub etag: bool,
pub mode: bool,
pub version: bool,
...
}- Add method to Operator to query capabilities:
impl Operator {
pub fn metadata_capability(&self) -> MetadataCapability;
}- Modify list operation to avoid implicit stat calls
- Update all service implementations to declare their metadata capabilities
Each service implementation will need to:
- Remove
Metakeyhandling logic - Implement
metadata_capability()to accurately indicate the metadata provided by default - Ensure list operations return metadata that’s always available without extra API calls
§Drawbacks
- Breaking change for existing users
- Loss of fine-grained control over metadata fetching
- Potential increased API calls if users need multiple metadata fields
§Rationale and alternatives
This design is superior because:
- Prevents performance pitfalls by default
- Makes metadata availability explicitly
- Simplifies service implementation
- Provides clearer mental model
Alternatives considered:
- Keep
Metakeybut make it more restrictive - Add warnings for potentially costly operations
- Make stat calls async/lazy
Not making this change would continue the current issues of performance problems and API misuse.
§Prior art
None
§Unresolved questions
None
§Future possibilities
- Add metadata prefetching optimization
- Add metadata caching layer
- Support for custom metadata fields
- Automated capability detection