# IPFS Client API Goals: - **Any client API should solve the issues from this [doc](https://hackmd.io/rxFtUuTdRTO4-nyAxPHNqQ).** - Be generic enough to allow integration in host applications that have different internals designs. - Hide IPFS details from hosts. - Support all major OSes. - Be usable as a C compatible ffi. WebIdl-like definition: ```idl // Implemented by objects receiving data. interface DataSink { void start(); void stop(); void error(error: String|SomeBetterErrorType) void data(buffer: Array<u8>); } // Makes it possible to cancel an ongoing request. // Needed when racing origin servers to cancel the // requests that won't be used. interface Cancelable { void cancel() } // Implemented by some object that can use the host internal capabilities, // or use fallback implementations provided by the IPFS client // library itself. interface HostDelegate { Cancelable fetchHttp(url: Url, sink: DataSink) Promise<String> dnsRecord(name: String, record: String) Promise<Array<u8>> fromCache(key: String) Promise<bool> toCache(key: String, data: Array<u8>) } // Main entry point: kicks off the process of fetching a ipfs url, // calling functions in `sink` as needed. Cancelable fetchIpfs(url: Url, host: HostDelegate, sink: DataSink) // Lower level api, fetching a CID Cancelable fetchCID(cid: String, host: HostDelegate, sink: DataSink) ``` # Rust definition ```rust pub trait DataSink { fn start(&self); fn stop(&self); fn error(&self, error: Error); fn data(&self, buffer: &[u8]); } pub trait Cancelable { fn cancel(&self); } #[async_trait] pub trait HostDelegate { fn fetch_http<S: DataSink>(&self, url: &Url, sink: S) -> impl Cancelable; async fn dns_record(&self, name: &str, record: &str) -> Result<String>; async fn from_cache(&self, key: &str) -> Result<Vec<u8>>; async fn to_cache(&self, key: &str, data: &[u8]) -> Result<()>; } pub fn fetch_ipfs<H: HostDelegate, S: DataSink>(url: &Url, delegate: H, sink: S) -> impl Cancelable { todo!(); } pub fn fetch_cid<H: HostDelegate, S: DataSink>(cid: &CID, delegate: H, sink: S) -> impl Cancelable { todo!(); } ```` # C ffi ```c typedef struct ipfs_data_sink* ipfs_data_sink_ptr; struct ipfs_data_sink { void (*start)(); void (*stop)(); void (*error)(char *error); void (*data)(char *buffer, int len); }; typedef void (*string_fn)(char *result); typedef void (*buffer_fn)(char *buffer, int len); typedef void (*void_fn)(); typedef ipfs_request_ptr void*; typedef struct ipfs_host_delegate* ipfs_host_delegate_ptr; struct ipfs_host_delegate { ipfs_request_ptr (*fetch_http)(char *url, ipfs_data_sink_ptr sink); void (*dns_record)(char *name, char *record, string_fn callback); void (*from_cache)(char *key, buffer_fn callback); void (*to_cache)(char *key, char *buffer, int len, void_fn callback); }; ipfs_data_sink_ptr new_ipfs_data_sink(); void free_ipfs_data_sink(ipfs_data_sink_ptr delegate); ipfs_host_delegate_ptr new_ipfs_host_delegate(); void free_ipfs_host_delegate(ipfs_host_delegate_ptr delegate); ipfs_request_ptr ipfs_fetch(char* url, ipfs_host_delegate_ptr host, ipfs_data_sink_ptr sink); ipfs_request_ptr ipfs_fetch_cid(cid* url, ipfs_host_delegate_ptr host, ipfs_data_sink_ptr sink); void ipfs_cancel_request(ipfs_request_ptr* request); ```