multiformats / js-multiformats

Multiformats interface (multihash, multicodec, multibase and CID)
Other
224 stars 52 forks source link

consider adding `toURL` method to embed best practices of serializing cid to URL #71

Open Gozala opened 3 years ago

Gozala commented 3 years ago

There had been various discussions about the fact that in the wild we see IPFS urls to specific gateways. I think we can bake a best practice into CID implementation by adding a method like:

interface CID {
  // ... stuff we already have
  /**
   * Encodes CID into a URL object.
   *
   * @example
   * ```js
   * const cid = CID.parse('QmbrRJJNKmPDUAZ8CGwn1WNx2C7xP4J284VWoAUDaCiLaD')
   * cid.toURL().href // 'ipfs://bafybeigizayotjo4whdurcq6ge7nrgfyxox7ji7oviesmnvgrnxn3nakni/'
   * ```
   * 
   * Optionally you could provide a gateway URL to encode CID to a URL in that gateway.
   * @example
   * ```js
   * const cid = CID.parse('QmbrRJJNKmPDUAZ8CGwn1WNx2C7xP4J284VWoAUDaCiLaD')
   * cid.toURL({ gateway: new URL('https://dweb.link') }).href
   * // => 'https://dweb.link/ipfs/bafybeigizayotjo4whdurcq6ge7nrgfyxox7ji7oviesmnvgrnxn3nakni'
   * ```
   */
  toURL(options?: { gateway?: URL }):URL
}

Note that here we reinforce several of the best practices:

  1. ipfs://${cidv1} is the default that we to see.
  2. We want to encourage CID v1 because it addresses bunch of issues that we have with v0.
  3. ~Gateways URLs are origin separated.~
lidel commented 3 years ago

This sounds sensible, but you may want to update example to use generic path gateway:

-   * cid.toURL().href // 'https://bafybeigizayotjo4whdurcq6ge7nrgfyxox7ji7oviesmnvgrnxn3nakni.ipfs.dweb.link/'
+   * cid.toURL(new URL('https://dweb.link')).href // 'https://dweb.link/ipfs/bafybeigizayotjo4whdurcq6ge7nrgfyxox7ji7oviesmnvgrnxn3nakni'
vmx commented 3 years ago

I'm not sure about it. To me CID is a concept that is independent of IPFS. Hence I would rather put IPFS-style URL generation into a higher level library. Please consider this comment an opinion and not something blocking this effort.

yusefnapora commented 3 years ago

@vmx, perhaps one of the options could be scheme, which defaults to ipfs:// to allow you to use any protocol?

rvagg commented 3 years ago

There is an ongoing effort to try and reframe "IPFS" to be something other than the go-ipfs and js-ipfs instantiations and decouple it from the current 'IPFS DHT'. It goes something like this (iterating on language from Juan):

IPFS is:

  1. Content addressed data, using CIDs, formed into linkable graphs, using IPLD (broadly defined)
  2. Shared in a peer-to-peer manner

Which then encompasses go-ipfs, js-ipfs, the 'IPFS DHT' gateways, Filecoin and any other stack that uses CIDs to form DAGs with some form of ~p2p.

So when viewed in that lens, this change kind of makes sense landing here. It shouldn't be viewed as "this thing can be fetched from an IPFS gateway because it's in 'the IPFS DHT'". Rather, it should mean "this is an IPFS-style link to something, it can be found in the IPFS stack, but you may need further context to actually locate the block."