# 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);
```