This IPIP specifies an HTTP API for delegated content routing.
Idiomatic and first-class HTTP support for delegated routing is an important requirement for large content routing providers,
and supporting large content providers is a key strategy for driving down IPFS content routing latency.
These providers must handle high volumes of traffic and support many users, so leveraging industry-standard tools and services
such as HTTP load balancers, CDNs, reverse proxies, etc. is a requirement.
To maximize compatibility with standard tools, IPFS needs an HTTP API specification that uses standard HTTP idioms and payload encoding.
The Reframe spec for delegated content routing is an experimental attempt at this,
but it has resulted in a very unidiomatic HTTP API which is difficult to implement and is incompatible with many existing tools.
The cost of a proper redesign, implementation, and maintenance of Reframe and its implementation is too high relative to the urgency of having a delegated content routing HTTP API.
Note that this does not supplant nor deprecate Reframe. Ideally in the future, Reframe and its implementation would receive the resources needed to map the IDL to idiomatic HTTP,
and implementations of this spec could then be rewritten in the IDL, maintaining backwards compatibility.
We expect this API to be extended beyond "content routing" in the future, so additional IPIPs may rename this to something more general such as "Delegated Routing HTTP API".
3. Detailed design
See the Delegated Content Routing HTTP API spec ([http-routing-v1]) included with this IPIP.
4. Design rationale
To understand the design rationale, it is important to consider the concrete Reframe limitations that we know about:
Reframe method types using the HTTP transport are encoded inside IPLD-encoded messages
This prevents URL-based pattern matching on methods, which makes it hard and expensive to do basic HTTP scaling and optimizations:
Configuring different caching strategies for different methods
Configuring reverse proxies on a per-method basis
Routing methods to specific backends
Method-specific reverse proxy config such as timeouts
Developer UX is poor as a result, e.g. for CDN caching you must encode the entire request message and pass it as a query parameter
This was initially done by URL-escaping the raw bytes
Shipped in Kubo 0.16
Packing a CID into a struct, encoding it with DAG-CBOR, multibase-encoding that, percent-encoding that, and then passing it in a URL, rather than merely passing the CID in the URL, is needlessly complex from a user's perspective, and has already made it difficult to manually construct requests or interpret logs
Added complexity of "Cacheable" methods supporting both POSTs and GETs
The required streaming support and message groups add a lot of implementation complexity, but streaming does not currently work for cacheable methods sent over HTTP
Ex for FindProviders, the response is buffered anyway for ETag calculation
There are no limits on response sizes nor ways to impose limits and paginate
This is useful for routers that have highly variable resolution time, to send results as soon as possible, but this is not a use case we are focusing on right now and we can add it later
The Identify method is not implemented because it is not currently useful
This is because Reframe's ambition is to be a generic catch-all bag of methods across protocols, while delegated routing use case only requires a subset of its methods.
Client and server implementations are difficult to write correctly, because of the non-standard wire formats and conventions
The Go implementation is complex and brittle, and is currently maintained by IPFS Stewards who are already over-committed with other priorities
Only the HTTP transport has been designed and implemented, so it's unclear if the existing design will work for other transports, and what their use cases and requirements are
This means Reframe can't be trusted to be transport-agnostic until there is at least a second transport implemented (e.g. as a reframe-over-libp2p protocol)
There's naming confusion around "Reframe, the protocol" and "Reframe, the set of methods"
So this API proposal makes the following changes:
The Delegated Content Routing API is defined using HTTP semantics, and can be implemented without introducing Reframe concepts nor IPLD
There is a clear distinction between the Kubo RPC and the vendor-agnostic Routing V1 HTTP API.
"Method names" and cache-relevant parameters are pushed into the URL path
Streaming support is removed, and default response size limits are added.
We will add streaming support in a subsequent IPIP, but we are trying to minimize the scope of this IPIP to what is immediately useful
Bodies are encoded using idiomatic JSON, instead of using IPLD codecs, and are compatible with OpenAPI specifications
The JSON uses human-readable string encodings of common data types
CIDs are encoded as CIDv1 strings with a multibase prefix (e.g. base32), for consistency with CLIs, browsers, and gateway URLs
Multiaddrs use the human-readable format that is used in existing tools and Kubo CLI commands such as ipfs id or ipfs swarm peers
Byte array values, such as signatures, are multibase-encoded strings (with an m prefix indicating Base64)
The "Identify" method and "message groups" are not included
The "GetIPNS" and "PutIPNS" methods are not included. Instead, a separate Delegated IPNS HTTP API aims to firstly facilitate naming system delegation, and secondly, pave the way for future iterations of IPNS with less interdependency with content routing. For more information, see Delegated IPNS HTTP API ([ipip-0379]).
4.1 User benefit
The cost of building and operating content routing services will be much lower, as developers will be able to maximally reuse existing industry-standard tooling.
Users will not need to learn a new RPC protocol and tooling to consume or expose the API.
This will result in more content routing providers, each providing a better experience for users, driving down content routing latency across the IPFS network
and increasing data availability.
4.2.1 Backwards Compatibility
IPFS Stewards will implement this API in go-delegated-routing, using breaking changes in a new minor version.
the experimental support for Reframe in Kubo will be deprecated in the next release and delegated content routing will subsequently use this HTTP API.
We may decide to re-add Reframe support in the future once these issues have been resolved.-
4.2.2 Forwards Compatibility
Standard HTTP mechanisms for forward compatibility are used:
The API is versioned using a version number prefix in the path
The Accept and Content-Type headers are used for content type negotiation, allowing for backwards-compatible additions of new MIME types, hypothetically such as:
application/cbor for binary-encoded responses
application/x-ndjson for streamed responses
application/octet-stream if the content router can provide the content/block directly
New paths+methods can be introduced in a backwards-compatible way
Parameters can be added using either new query parameters or new fields in the request/response body.
Provider records are both opaque and versioned to allow evolution of schemas and semantics for the same transfer protocol
As a proof-of-concept, the tests for the initial implementation of this HTTP API were successfully tested with a libp2p transport using libp2p/go-libp2p-http, demonstrating viability for also using this API over libp2p.
All CID requests are sent to a central HTTPS endpoint as plain text, with TLS being the only protection against third-party observation.
The usual JSON parsing rules apply. To prevent potential Denial of Service (DoS) attack, clients should ignore responses larger than 100 providers and introduce a byte size limit that is applicable to their use case.
Reframe (general-purpose RPC) was evaluated, see "Design rationale" section for rationale why it was not selected.