IPFS API 实现文档

这篇简短的文档旨在为任何想知道 api-绑定的实现,特别是 go-ipfs{ipfs 的主要实现软件}的人们.

章节:

IPFS 类型

IPFS 使用一组 set值类型,可用于预先枚举:

  • <ipfs-path>是 unix 风格 的路径,从一开始/ipfs/<cid>/...要么/ipns/<hash>/...要么/ipns/<domain>/....
  • <hash>是 base58 编码multihash
  • cid是一个Multibase编码CID- 自描述内容寻址标识符

有关流的说明: IPFS 是一种流协议. 关于它的一切都可以流式传输. 导入文件时,API 请求,应旨在流入数据,并正确处理背压-back-pressure,以便 IPFS 节点可以顺序处理它而不会有太大的内存压力. (如果使用 HTTP,通常会,通过写入请求主体堵塞来处理此问题. )

API 传输

与其他所有内容一样,IPFS 旨在灵活地处理 API 传输. 目前,go-ipfs实现支持 进程内 API 和 HTTP API. 通过在传输上 映射 API 函数,可以轻松添加更多内容. (这类似于 gRPC 也是如此映射在传输之上,像 HTTP) .

映射到传输涉及利用 传输的功能 来表达函数调用. 例如:

API 传输的 CLI

在命令行中,IPFS 使用 传统的 flag 和 基于 arg 的映射,其中:

  • 第一个参数选择命令,如在 git 中 - 例如ipfs object get
  • flag 指定选项 - 例如--enc=protobuf -q
  • 其余的是位置参数 - 例如ipfs object patch <hash1> add-linkfoo <hash2>
  • 文件由 filename 或 stdin 指定

(注意: 当 go-ipfs 运行守护进程时,CLI API 实际上转换为 HTTP 调用. 否则,它们在同一进程中执行)

HTTP API 传输

在 HTTP 中,我们的 API 分层 使用类似 REST 的映射,其中:

  • URL 路径选择命令 - 例如:/object/get
  • URL 查询字符串 实现 选项参数 - 例如:&enc=protobuf&q=true
  • URL 查询 还实现 位置参数 - 例如:&arg=<hash1>&arg=add-link&arg=foo&arg=<hash2>
  • 请求主体流文件数据 - 读取文件 或 stdin

    • 多个流与多部分复用 (todo: 添加 tar 流 支持)

API 命令

这是”标准 IPFS API”,当前定义为”go-ipfs 实现所公开的所有命令”. 有自动生成API 文档,你也可以看看在这里列出,或通过运行ipfs commands获取命令列表.

实现 HTTP API 的绑定

如上所述,API 命令映射到 HTTP:

  • URL 路径 选择 命令 - 例如/object/get
  • URL 查询字符串 实现 选项参数 - 例如&enc=protobuf&q=true
  • URL 查询 还实现 位置参数 - 例如&arg=<hash1>&arg=add-link&arg=foo&arg=<hash2>
  • 请求主体流文件数据 - 读取文件 或 stdin
    • 多个流与多部分复用 (todo: 添加 tar 流支持)

到目前为止,我们有两个不同的 HTTP API 客户端:

Go 实现很适合回答更难的问题,例如如何处理 多部分,或者在边缘条件下应该设置哪些标题. 但是 javascript 实现也非常简洁,易于遵循.

node-ipfs-api 的剖析

目前,node-ipfs-api 有三个主要文件

  • src/index.js定义 API 模块的客户端将使用的函数. 使用RequestAPI,几乎直接将 函数调用参数 转换为 API.
  • src/get-files-stream.js实现最难的部分: 文件流. 这个使用 multipart.
  • src/request-api.js泛型函数调用 来执行实际的 HTTP 请求

关于 multipart + 检查 请求 的注意事项

尽管上面已经说过所有的概括,但 IPFS API 实际上非常简单. 您可以检查所有请求带nc--api选项 (截至这个 PR, 要么0.3.8) :

  1. > nc -l 5002 &
  2. > ipfs --api /ip4/127.0.0.1/tcp/5002 swarm addrs local --enc=json
  3. POST /api/v0/version?enc=json&stream-channels=true HTTP/1.1
  4. Host: 127.0.0.1:5002
  5. User-Agent: /go-ipfs/0.3.8/
  6. Content-Length: 0
  7. Content-Type: application/octet-stream
  8. Accept-Encoding: gzip

唯一困难的部分是让文件流正确. (现在) 使用 multipart 将文件流式传输到 go-ipfs 相当容易. 基本上,我们最终得到这样的 HTTP 请求:

  1. > nc -l 5002 &
  2. > ipfs --api /ip4/127.0.0.1/tcp/5002 add -r ~/demo/basic/test
  3. POST /api/v0/add?encoding=json&progress=true&r=true&stream-channels=true HTTP/1.1
  4. Host: 127.0.0.1:5002
  5. User-Agent: /go-ipfs/0.3.8/
  6. Transfer-Encoding: chunked
  7. Content-Disposition: form-data: name="files"
  8. Content-Type: multipart/form-data; boundary=2186ef15d8f2c4f100af72d6d345afe36a4d17ef11264ec5b8ec4436447f
  9. Accept-Encoding: gzip
  10. 1
  11. -
  12. e5
  13. -2186ef15d8f2c4f100af72d6d345afe36a4d17ef11264ec5b8ec4436447f
  14. Content-Disposition: form-data; name="file"; filename="test"
  15. Content-Type: multipart/mixed; boundary=acdb172fe12f25e8ffae9981ce6f4580abdefb0cae3ceebe464d802866be
  16. 9c
  17. --acdb172fe12f25e8ffae9981ce6f4580abdefb0cae3ceebe464d802866be
  18. Content-Disposition: file; filename="test%2Fbar"
  19. Content-Type: application/octet-stream
  20. 4
  21. bar
  22. dc
  23. --acdb172fe12f25e8ffae9981ce6f4580abdefb0cae3ceebe464d802866be
  24. Content-Disposition: file; filename="test%2Fbaz"
  25. Content-Type: multipart/mixed; boundary=2799ac77a72ef7b8a0281945806b9f9a28f7681145aa8e91b052d599b2dd
  26. a0
  27. --2799ac77a72ef7b8a0281945806b9f9a28f7681145aa8e91b052d599b2dd
  28. Content-Type: application/octet-stream
  29. Content-Disposition: file; filename="test%2Fbaz%2Fb"
  30. 4
  31. bar
  32. a2
  33. --2799ac77a72ef7b8a0281945806b9f9a28f7681145aa8e91b052d599b2dd
  34. Content-Disposition: file; filename="test%2Fbaz%2Ff"
  35. Content-Type: application/octet-stream
  36. 4
  37. foo
  38. 44
  39. --2799ac77a72ef7b8a0281945806b9f9a28f7681145aa8e91b052d599b2dd--
  40. 9e
  41. --acdb172fe12f25e8ffae9981ce6f4580abdefb0cae3ceebe464d802866be
  42. Content-Disposition: file; filename="test%2Ffoo"
  43. Content-Type: application/octet-stream
  44. 4
  45. foo
  46. 44
  47. --acdb172fe12f25e8ffae9981ce6f4580abdefb0cae3ceebe464d802866be--
  48. 44
  49. --2186ef15d8f2c4f100af72d6d345afe36a4d17ef11264ec5b8ec4436447f--
  50. 0

是在这里产生的: http://gateway.ipfs.io/ipfs/QmNtpA5TBNqHrKf3cLQ1AiUKXiE4JmUodbG5gXrajg8wdv