Skip to content

CouchDB - HTTP API

CouchDB 是一个 API 优先的数据库。所有交互,从创建数据库到查询复杂数据,都通过其 RESTful HTTP API 进行。这种设计使 CouchDB 具有令人难以置信的多功能性,允许任何能够发出 HTTP 请求的语言或工具成为 CouchDB 客户端。数据几乎总是以 JSON(JavaScript Object Notation,JavaScript 对象表示法)格式发送和接收。

您将使用标准的 HTTP 方法来向数据库传达您的意图。可以将它们视为管理数据的“动词”:

  • GET:检索资源。这可以是关于服务器、数据库、特定文档的信息,或者查询的结果。
  • HEAD:与 GET 相同,但只检索响应的 HTTP 头部,而不包括响应体。用于检查资源状态或版本号(_rev),而无需下载整个有效负载。
  • POST:创建新资源而不指定其 ID(让 CouchDB 自动生成),或者执行特殊操作,例如使用 Mango _find 端点进行查询,或使用 _bulk_docs 进行批量操作。
  • PUT:在特定的、由客户端命名的 URL 上创建或更新资源。用于创建命名数据库以及创建或更新已知 _id 的文档。
  • DELETE:移除资源,例如文档或数据库。此操作是永久性的。
  • COPY:CouchDB 使用的一种特殊的非标准方法,用于复制文档。它是 GET 后跟 PUT 操作的便捷快捷方式。

尽管有许多可用头部,但以下两个对大多数交互至关重要:

  • Content-Type:当您向 CouchDB 发送数据(使用 PUT 或 POST)时,必须指定其格式。对于几乎所有的数据库操作,这都将是 application/json。
  • Accept:告知 CouchDB 您的客户端希望响应采用哪种数据格式。尽管通常是可选的,但最佳实践是指定 application/json 以确保您获得可预测的 JSON 输出。

服务器的响应头部提供了有关请求结果的重要元数据:

  • Content-Type:指定响应体的 MIME 类型,通常是 application/json 或 text/plain; charset=utf-8。
  • Content-Length:响应体的大小(以字节为单位)。
  • Etag:对于文档和视图响应,此头部包含文档的版本值(例如,"1-a954784578bca65545a1989467262913")。这与 JSON 正文中的 _rev 字段相同,对于缓存和冲突管理至关重要。
  • Cache-Control:提供缓存指令。CouchDB 通常返回 must-revalidate,表示缓存在使用缓存副本之前应确认资源仍是最新。

理解状态码是构建健壮应用程序的关键。以下是您将遇到的最常见状态码:

代码含义与上下文
200 OK请求成功。用于成功的 GET 和 PUT 更新。
201 Created资源(数据库或文档)已成功创建。用于成功的 PUT 创建和部分 POST 请求。
202 Accepted请求已被接受进行后台处理,例如数据库压缩。
304 Not Modified与条件请求(例如,带有 Etag 的 If-None-Match 头部)一起使用,表示资源未更改。
400 Bad Request请求格式不正确。JSON 正文可能无效,或者查询参数不正确。
401 Unauthorized需要身份验证,但未提供凭据或凭据不正确。
404 Not Found请求的资源(数据库、文档、视图)不存在。
409 Conflict文档更新无法完成。这几乎总是意味着您提供的 _rev 不是最新版本。这是一个核心特性,而不是一个需要担心的错误!
500 Internal Server Error服务器内部发生错误。请检查 CouchDB 日志获取详细信息。

尽管传统的 MapReduce 视图功能强大,但现代 CouchDB (2.0+) 提供了 Mango 查询引擎,它提供了一种简单、声明式的基于 JSON 的方式来查询数据。对于常见用例,它通常更简单、更直观。

要使用它,您需要将一个选择器对象 POST 到数据库的 /_find 端点。首先,您需要在要查询的字段上创建索引。

首先,在“role”字段上创建一个索引:

POST /users/_index
Content-Type: application/json
{
"index": {
"fields": ["role"]
},
"name": "role-index",
"type": "json"
}

然后,查询所有角色为“admin”的用户:

POST /users/_find
Content-Type: application/json
{
"selector": {
"role": "admin"
}
}