APIs should provide clean abstraction boundaries without exposing internal implementation details or creating unwanted dependencies between modules. When designing public interfaces, carefully consider what needs to be exposed versus what can remain internal.
APIs should provide clean abstraction boundaries without exposing internal implementation details or creating unwanted dependencies between modules. When designing public interfaces, carefully consider what needs to be exposed versus what can remain internal.
Common violations include:
Instead, prefer:
pub use quinn::ConnectionError;
rather than pub use quinn;
Example of good abstraction:
// Instead of exposing complex internal resolver
pub fn op_require_fallback_resolve<T: NodeRequireLoader>(
state: &mut OpState,
request: String,
parent_filename: Option<String>,
) -> Result<String, RequireError>
// Expose simpler options-based API
#[derive(Debug, Default, Clone)]
pub struct ConditionOptions {
pub conditions: Vec<Cow<'static, str>>,
pub import_conditions_override: Option<Vec<Cow<'static, str>>>,
}
This approach reduces coupling, improves maintainability, and provides cleaner interfaces for API consumers.
Enter the URL of a public GitHub repository