|
| 1 | +# IPIP 0000: Delegated Routing HTTP API |
| 2 | + |
| 3 | +- Start Date: 2022-10-18 |
| 4 | +- Related Issues: |
| 5 | + - (add links here) |
| 6 | + |
| 7 | +## Summary |
| 8 | + |
| 9 | +This IPIP specifies an HTTP API for delegated routing. |
| 10 | + |
| 11 | +## Motivation |
| 12 | + |
| 13 | +Idiomatic and first-class HTTP support for delegated routing is an important requirement for large content routing providers, |
| 14 | +and supporting large content providers is a key strategy for driving down IPFS latency. |
| 15 | +These providers must handle high volumes of traffic and support many users, so leveraging industry-standard tools and services |
| 16 | +such as HTTP load balancers, CDNs, reverse proxies, etc. is a requirement. |
| 17 | +To maximize compatibility with standard tools, IPFS needs an HTTP API specification that uses standard HTTP idioms and payload encoding. |
| 18 | +The [Reframe spec](https://github.com/ipfs/specs/blob/main/reframe/REFRAME_PROTOCOL.md) for delegated content routing was an experimental attempt at this, |
| 19 | +but it has resulted in a very unidiomatic HTTP API which is difficult to implement and is incompatible with many existing tools. |
| 20 | +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 routing HTTP API. |
| 21 | + |
| 22 | +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, |
| 23 | +and this spec could then be rewritten in the IDL, maintaining backwards compatibility. |
| 24 | + |
| 25 | +## Detailed design |
| 26 | + |
| 27 | +See the [API design](../routing/DELEGATED_ROUTING_HTTP.md) included with this IPIP. |
| 28 | + |
| 29 | +## Design rationale |
| 30 | +To understand the design rationale, it is important to consider the concrete Reframe limitations that we know about: |
| 31 | + |
| 32 | +- Reframe methods are encoded inside messages |
| 33 | + - This prevents URL-based pattern matching on methods |
| 34 | + - Configuring different caching strategies for different methods |
| 35 | + - Configuring reverse proxies on a per-method basis |
| 36 | + - Routing methods to specific backends |
| 37 | + - Method-specific reverse proxy config such as timeouts |
| 38 | + - 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 |
| 39 | + - This was initially done by URL-escaping the raw bytes |
| 40 | + - Not possible to consume correctly using standard JavaScript |
| 41 | + - Shipped in Kubo 0.16 |
| 42 | + - 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 |
| 43 | + - Added complexity of "Cacheable" methods supporting both POSTs and GETs |
| 44 | +- The required streaming support and message groups add a lot of implementation complexity but isn’t very useful |
| 45 | + - Ex for FindProviders, the response is buffered anyway for ETag calculation |
| 46 | + - There are no limits on response sizes nor ways to impose limits and paginate |
| 47 | + - 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 |
| 48 | +- The Identify method is not implemented because it is not currently useful |
| 49 | +- Client and server implementations are difficult to write correctly, because of the non-standard wire formats and conventions |
| 50 | +- The Go implementation is [complex](https://github.com/ipfs/go-delegated-routing/blob/main/gen/proto/proto_edelweiss.go) and [brittle](https://github.com/ipfs/go-delegated-routing/blame/main/client/provide.go#L51), and is currently maintained by IPFS Stewards who are already over-committed with other priorities |
| 51 | +- 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 |
| 52 | + |
| 53 | +So this API proposal makes the following changes: |
| 54 | + |
| 55 | +- The API is defined in HTTP directly |
| 56 | +- "Methods" and cache-relevant parameters are pushed into the URL path |
| 57 | +- Streaming support is removed, and optional pagination is added, which limits the response size and provides a scalable mechanism for iterating over arbitrarily-large collections |
| 58 | + - We might add streaming support w/ chunked-encoded responses in the future, but it's currently not an important feature for the use cases that an HTTP API will be used for |
| 59 | +- Bodies are encoded using standard JSON or CBOR, instead of using IPLD codecs |
| 60 | +- The "Identify" method and "message groups" are removed |
| 61 | + |
| 62 | +### User benefit |
| 63 | + |
| 64 | +The cost of building and operating content routing services will be much lower, as developers will be able to reuse existing industry-standard tooling. |
| 65 | +This will result in more content routing providers, each providing a better experience for users, driving down content routing latency across the IPFS netowrk |
| 66 | +and increasing data availability. |
| 67 | + |
| 68 | +### Compatibility |
| 69 | + |
| 70 | +#### Backwards Compatibility |
| 71 | +IPFS Stewards will implement this API in [go-delegated-routing](https://github.com/ipfs/go-delegated-routing), using breaking changes in a new minor version. |
| 72 | +Because the existing Reframe spec can't be safely used in JavaScript, the experimental support for Reframe in Kubo will be removed in the next release, |
| 73 | +and delegated routing will subsequently use this HTTP API. We may decide to re-add Reframe support in the future once these issues have been resolved. |
| 74 | + |
| 75 | +#### Forwards Compatibility |
| 76 | +Standard HTTP mechanisms for forward compatibility are used--the API is versioned using a version number in the path. The `Accept` and `Content-Type` headers are used for content type negotiation. new methods will result in new paths, and parameters can be added using either new query parameters or new fields in the request/response body. Certain parts of bodies are labeled as "opaque bytes", which are passed through by the implementation, with no schema enforcement. |
| 77 | + |
| 78 | +### Security |
| 79 | + |
| 80 | +None |
| 81 | + |
| 82 | +### Alternatives |
| 83 | + |
| 84 | +This *is* an alternative. |
| 85 | + |
| 86 | +### Copyright |
| 87 | + |
| 88 | +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). |
0 commit comments