# IPFS Client API braindump
## Usecase story (ffmpeg)
The ffmpeg integration thought me a couple lessons. First and foremost it's very difficult to explain the IPFS concepts when there are no real specs to point to. To a project like that where the IPFS implementation is essentially a glorified url parser and rewriter it's hard to sell the need for them to accpet a patch. Specifically if gateway urls (`https://<gateway>/ipfs/<cid>`) already works, it seems pointless to them to allow `ipfs://<cid>`
They are not alone in their hesitance to accept that. Curl also needed a lot of convincing to allow that seemingly simple concept.
Challenges:
* no spec
* can't load ipfs as a library
* system is not a daemon, runs transitory
* want to reduce amount of change an integration target has to deal with
* ffmpeg library needs file-oriented api, but js might need data+file-oriented
## Usecases
* The sell of "implementing IPFS" with the unique IPFS requirements (like finding a gateway, getting data through it, etc..) is a very hard one. We should aim to sell a "library" with common functions that gives the application, using the library, IPFS support.
* This also gives freedom on the IPFS side to still change the inner workings of that library as long as the external facing API is left untouched.
* A library with familiar ways to handle files is a much easier ask for a project to use.
## Caveats
* When going for a library it sorta implies the functionality is opt-in. Say with ffmpeg as an example again. If IPFS were to be a library then that would have to be linked against at compile time. That would most certainly have to be flag (like `--enable-ipfs`) that wouldn't be enabled by default.
* Which then gives the burden of "begging" distributions to change their ffmpeg build flags to enable IPFS.
* Complicated binary prebuilds as they too would have to enable it.
## API ideas
* access ipfs data as if they are files in an API that feels familiar for files. I'd suggest the posix API but there are other ways.
* Could also be an entirely different style API like for example callback based (think http fetch)
* We do want to provide control over which parts to "fetch", as that allows for seeking functionality. Not important for downloading a file but important for media purposes (video/audio)
* Gateway should be fully handled inside this API. Externally and as an API user you should not need to know a single thing about gateways.
* This implies:
* Racing gateway
* The API to look for a gateway you might have running already (gateway file, IPFS_GATEWAY environment variable or even one broadcasted on mdns)
## How do you find gateways?
* mdns - local network discovery
* IPFS_GATEWAY, gatewayfile
* Public Gateway Checker list
* Some programmatic+network method
* pubsub channel?
* new Gateway API?
* underlying Kubo API?
Challenges:
* feature support - eg DNSLink, subdomain, trustless
*
# API design
This is where the fun starts!
basic
* open
* read
* seek
* close
streams
* {tbd}
Reference
* node: https://nodejs.org/api/fs.html
* posix: https://www.mkompf.com/cplus/posixlist.html
* c++ iostream: https://cplusplus.com/reference/istream/iostream/
# Questions
* how does this map to B5's ipfs "levels"
* not mature enough overall
* but level 0 and 1 are usable
* level 2 - writable, not clear yet
# Defining error handling
* Language agnostic error codes
* Must match posix as closely as possible
* Should include extensibility (eg HTTP response data from gateways)
# Q3:
- Proof of concept quality (i.o.t. Working but very hacky)
- Level 0
- c-based approach (basic from API design, file API)
### "Caching" Gateway
How Durin works => https://github.com/ipfs-shipyard/Durin/blob/ec4408583a9731e3447e8a23a58226201b7b5b5b/src/util/ipfs.ts#L74
1. Do a health check against a default list of hardcoded gateways on app startup
2. "health check" means, gateways are fetched concurrently and sorted by two metrics: "Health" and Speed.
3. Top gateway from this list is used until health check is run again on interval.