Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IPIP-0388: Routing HTTP API Support for Querying Multiple Routers #388

Draft
wants to merge 7 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions IPIP/0388-routing-v1-multiple-routers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# IPIP-0388: Routing HTTP API Support for Querying Multiple Routers

<!-- IPIP number should match its pull request number. After you open a PR,
please update title and include an abbreviated title in the filename too:
`0000-draft-title-abbrev.md`. -->

- Start Date: 2023-03-20
- Related Issues:
- https://github.com/ipfs-shipyard/someguy/issues/12
- https://github.com/ipfs-shipyard/someguy/issues/13
- https://github.com/ipfs/bifrost-gateway/issues/151

## Summary

Adding support for querying individual routers to a single Routing v1 HTTP endpoint.

## Motivation

At the moment there is no way for a Routing v1 client to ask for a specific routing backend to be used nor for a Routing v1 endpoint to signal what routing backends they support. When Routing v1 is used as a proxy for one or more routing systems (e.g. IPFS Public DHT, IPNI, mainlineDHT, ...) clients may want to be able to judge a given endpoint's suitability to be a proxy for that routing system.

For instance if all-the-routers.alice.tld is very good at proxying IPNI requests but bad at proxying IPFS Public DHT requests, but dht-proxy.bob.tld is good at proxying IPFS Public DHT requests. In this scenario clients wanting good responses would have to ask both Alice and Bob to do DHT lookups for them even though Alice's DHT lookups are unneccessary because Bob is doing them. Similarly, clients could evaluate the best endpoint to request responses from since they can now do comparisons between largely equivalent routing systems. Additionally, this allows clients to discover the data sources behind Routing v1 endpoints without as much out of band information.

## Detailed design

AKA Solution Proposal

The proposal is to:
1. Add a `?routing=<list-of-routers>` optional parameter to `GET /routing/v1/providers/{CID}` that indicates which routing systems to use
2. Add an `OPTIONS /routing/v1/providers` endpoint which when queried may respond with a `Ipfs-Supported-Routers` HTTP header, with the value as the comma separated list of the routing systems supported

## Design rationale

The rationale fleshes out the specification by describing what motivated
the design and why particular design decisions were made.

Provide evidence of rough consensus and working code within the community,
and discuss important objections or concerns raised during discussion.

### User benefit

End users will be able to query endpoints that provide proxies for multiple routing systems (e.g. cid.contact/routing/v1) and get back DHT, IPNI or both depending on what they need.

For users that are running a DHT client locally they can dynamically evaluate if cid.contact's DHT proxy is either good enough that they can conserve their local resources by reducing how they use their client. Similarly, if they discover that their local DHT results are better than cid.contact's DHT proxy then they can ease the burden on cid.contact by only requesting IPNI results and doing the DHT lookups themselves.

### Compatibility

This should not effect existing clients or servers

### Security

Mostly not applicable. However, clients should not expect proxies to give 1:1 mappings with the underlying systems if they are too expensive and should consider that when evaluating the performance of individual endpoints.

### Alternatives

- Having clients fetch from multiple sources which may have overlapping data -> lots of work on servers and extra processing work for clients
- Having clients fetch from a single source with the best data -> is not friendly to the introduction of new services and may result in less data being retrieved
- Having servers restrict to one endpoint per router (e.g. dht.alice.tld and ipni.alice.tld or alice.tld/dht/routing/v1 and alice.tld/ipni/routing/v1) -> also doable, but discoverability of new router types would require other semantics (e.g. an OPTIONS request to alice.tld/routing/v1)
- Having `OPTIONS` on `/routing/v1` instead of `/routing/v1/providers` -> also good, perhaps a better choice. given that not every router will support every request type there's a tradeoff around how low level you put the `OPTIONS`. In theory both could be supported.
- Having `OPTIONS` on `/routing/v1/providers/{CID}` in the event the CID tells you some information about which providers to use (e.g. for non-BitTorrent codecs don't use mainline DHT) -> also doable. Unclear if this would be useful in practice since sometimes the codec information will get lost (e.g. replaced with the raw/0x55 codec).

### Copyright

Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).
20 changes: 19 additions & 1 deletion routing/ROUTING_V1_HTTP.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ Specifications for some transfer protocols are provided in the "Transfer Protoco

## API

### `GET /routing/v1/providers/{CID}`
### `GET /routing/v1/providers/{CID}[?routers=<list-of-routers>]`

#### Response codes

Expand All @@ -90,6 +90,18 @@ Response limit: 100 providers

Each object in the `Providers` list is a *read provider record*.

#### List of Routers

A list of routers that should be consulted for responses. The specification imposes no constraints on the order by which the results are returned. Implementers are free to return results as they are found.

If none are provided the backend may decide which ones to use. For a list of known routers see below.

To select all routers use `?routers=*`. To determine the list of available routers see the `OPTIONS` API below

### `OPTIONS /routing/v1/providers`
Copy link
Member

@lidel lidel Jun 27, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some quick thoughts:

  • Learning about available routers via OPTIONS header is ok, but just for the record, it introduces some UX challenges:
    • can't paste link in address bar: need to pass custom method to curl -X OPTIONS, JS may need explicit entry in Access-Control-Expose-Headers for the value to be readable via JS.
  • Given the design decisions made when we abandoned Reframe and prioritized user-friendliness and human-readablinity of API, it may be a better UX and less headache to support listing available routers via GET and return them as JSON.

Alternative idea just to see if it resonates better:

Request: GET /routing/v1/routers (dedicated endpoint)

Response: JSON with list of items following router schema

{
  "Schema": "router",
  "Name": "ipfs-public-dht",
  "Default": false, // is it used when `?routers` is not passed
  "RoutingType": ["providers", "ipns", "peers"], // where can it be used
  "Details": { .. } // optional opaque JSON with router-type-specific values
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rebased this IPIP on top of latest spec, and replaced OPTIONS with GET /routing/v1/routers and a router schema above.


If supported the server should include an `Ipfs-Supported-Routers` header key, with the value as the comma separated list of the routing systems supported.

## Pagination

This API does not support pagination, but optional pagination can be added in a backwards-compatible spec update.
Expand Down Expand Up @@ -173,3 +185,9 @@ Specification: [ipfs/go-graphsync/blob/main/docs/architecture.md](https://github
- `PieceCID`: the CID of the [piece](https://spec.filecoin.io/systems/filecoin_files/piece/#section-systems.filecoin_files.piece) within which the data is stored
- `VerifiedDeal`: whether the deal corresponding to the data is verified
- `FastRetrieval`: whether the provider claims there is an unsealed copy of the data available for fast retrieval

## Known Routers

This section contains a non-exhaustive list of known routers that may be supported by clients and servers.

- "ipfs-public-dht" - The IPFS Public DHT corresponding to the libp2p protocol ID `/ipfs/kad/1.0.0`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we include / how should we name 'server's connected bitswap peers'?

Copy link
Member

@lidel lidel Jun 27, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ipfs-bitswap-peers ?
I think it is ok to define some canonical names for popular things here, but the spec should be clear that it is at liberty of implementer to use other, opaque strings (for custom / future routing systems)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've removed this list from the IPIP and added sentence that these are opaque strings controlled by implementation/instance.

lidel marked this conversation as resolved.
Show resolved Hide resolved