Основы API
API CouchDB — основной способ взаимодействия с экземпляром CouchDB. Запросы выполняются с помощью HTTP и используются для получения информации из базы данных, сохранения новых данных, а также создания представлений и форматирования информации, хранящейся в документах.
Запросы к API можно классифицировать по различным областям системы CouchDB, к которым вы обращаетесь, и по HTTP-методу, используемому для отправки запроса. Разные методы подразумевают разные операции: например, получение информации из базы данных обычно выполняется с помощью операции GET, а обновление — с помощью запроса POST или PUT. Для разных методов необходимо предоставлять разные данные. Руководство по основным методам HTTP и структуре запросов см. в разделе Формат запросов и ответы.
Почти для всех операций отправляемые данные и структура возвращаемых данных определяются в объекте JavaScript Object Notation (JSON). Основные сведения о содержимом и типах данных JSON приведены в разделе Основы JSON.
Об ошибках при обращении к API CouchDB сообщается с помощью стандартных кодов состояния HTTP. Описание общих кодов, возвращаемых CouchDB, приведено в разделе Коды состояния HTTP.
Для конкретных областей API CouchDB приведены сведения и примеры HTTP-методов и запросов, структур JSON и кодов ошибок.
Формат запросов и ответы
CouchDB поддерживает следующие методы HTTP-запросов:
-
GETЗапрашивает указанный элемент. Как и в обычных HTTP-запросах, формат URL определяет, что будет возвращено. В CouchDB это могут быть статические элементы, документы базы данных, а также сведения о конфигурации и статистике. В большинстве случаев информация возвращается в виде документа JSON.
-
HEADМетод
HEADиспользуется для получения HTTP-заголовка запросаGETбез тела ответа. -
POSTЗагружает данные. В CouchDB
POSTиспользуется для задания значений, в том числе для загрузки документов, задания значений документов и запуска некоторых команд администрирования. -
PUTИспользуется для размещения указанного ресурса. В CouchDB
PUTиспользуется для создания новых объектов, включая базы данных, документы, представления и документы дизайна. -
DELETEУдаляет указанный ресурс, включая документы, представления и документы дизайна.
-
COPYСпециальный метод, который можно использовать для копирования документов и объектов.
Если использовать неподдерживаемый тип HTTP-запроса с URL, не поддерживающим этот тип, будет возвращён ответ 405 - Method Not Allowed со списком поддерживаемых методов HTTP. Например:
{
"error":"method_not_allowed",
"reason":"Only GET,HEAD allowed"
} Заголовки HTTP
Поскольку CouchDB использует HTTP для всех видов взаимодействия, необходимо убедиться, что указаны правильные HTTP-заголовки (и что они обрабатываются при получении данных), чтобы получить данные в нужном формате и кодировке. Разные среды и клиенты могут по-разному строго относиться к наличию этих HTTP-заголовков и их влиянию на обработку данных. По возможности указывайте их как можно точнее.
Заголовки запросов
-
AcceptУказывает список типов данных, которые сервер может вернуть и которые клиент принимает или способен обработать. Значение должно представлять собой список одного или нескольких MIME-типов, разделённых двоеточиями.
Для большинства запросов следует указать тип данных JSON (
application/json). Для вложений можно явно указать MIME-тип или использовать*/*, чтобы указать, что поддерживаются все типы файлов. Если заголовокAcceptне указан, предполагается MIME-тип*/*(то есть клиент принимает все форматы).Использовать
Acceptв запросах к CouchDB необязательно, но настоятельно рекомендуется: это помогает убедиться, что клиент сможет обработать возвращённые данные.Если указать тип данных с помощью заголовка
Accept, CouchDB применит указанный тип в возвращаемом поле заголовкаContent-type. Например, если явно запроситьapplication/jsonвAcceptзапроса, в возвращённых HTTP-заголовках будет использоваться значение поляContent-type.Например, при отправке запроса без явно указанного заголовка
Acceptили при указании*/*:GET /recipes HTTP/1.1 Host: couchdb:5984 Accept: */*
Возвращаются следующие заголовки:
HTTP/1.1 200 OK Server: CouchDB (Erlang/OTP) Date: Thu, 13 Jan 2011 13:39:34 GMT Content-Type: text/plain;charset=utf-8 Content-Length: 227 Cache-Control: must-revalidate
Примечание
Возвращаемый тип содержимого —
text/plain, хотя данные, возвращённые запросом, представлены в формате JSON.Явное указание заголовка
Accept:GET /recipes HTTP/1.1 Host: couchdb:5984 Accept: application/json
Среди возвращённых заголовков есть тип содержимого
application/json:HTTP/1.1 200 OK Server: CouchDB (Erlang/OTP) Date: Thu, 13 Jan 2013 13:40:11 GMT Content-Type: application/json Content-Length: 227 Cache-Control: must-revalidate
-
Content-typeУказывает тип содержимого данных, передаваемых в запросе. Для указания используются MIME-типы. Для большинства запросов это будет JSON (
application/json). Для некоторых параметров MIME-типом будет обычный текст. При загрузке вложений следует указать соответствующий MIME-тип вложения или двоичный тип (application/octet-stream).Настоятельно рекомендуется указывать
Content-typeв запросе. -
X-Couch-Request-ID(Необязательно) CouchDB добавляет заголовок
X-Couch-Request-IDк каждому ответу, чтобы пользователям было проще сопоставить возникшую проблему с журналом CouchDB.Если этот заголовок присутствует в запросе (и его значение не превышает 36 символов из набора
0-9a-zA-z-_), это значение будет использоваться внутри системы какnonceзапроса, которое отображается в журналах, а также возвращаться в заголовке ответаX-Couch-Request-ID.
Заголовки ответов
Сервер возвращает заголовки ответов вместе с содержимым. Они включают различные поля заголовков, многие из которых являются стандартными заголовками HTTP-ответа и не имеют значения для работы CouchDB. Ниже перечислены заголовки ответов, важные для CouchDB.
-
Cache-controlЗаголовок HTTP-ответа управления кэшированием содержит рекомендации для механизмов кэширования клиента о том, как обрабатывать возвращённые данные. Обычно CouchDB возвращает
must-revalidate, указывая, что при возможности данные следует проверить повторно. Это позволяет правильно обновлять динамическое содержимое. -
Content-lengthДлина возвращённого содержимого в байтах.
-
Content-typeУказывает MIME-тип возвращённых данных. Для большинства запросов возвращается MIME-тип
text/plain. Весь текст кодируется в Unicode (UTF-8), что явно указывается в возвращённомContent-typeкакtext/plain;charset=utf-8. -
EtagПоле HTTP-заголовка
Etagиспользуется для указания ревизии документа или представления.ETag назначаются группе map/reduce (набору представлений в одном документе дизайна). Любое изменение индексов этих представлений приводит к созданию нового ETag для всех URL представлений в одном документе дизайна, даже если результаты конкретного представления не изменились.
У каждого URL
_viewсвой ETag, который обновляется только при изменениях базы данных, влияющих на соответствующий индекс. Если индекс этого представления не меняется, у него сохраняется исходный ETag (поэтому ответ304 - Not Modifiedотправляется чаще). -
Transfer-EncodingЕсли в ответе используется кодировка, она указывается в этом поле заголовка.
Transfer-Encoding: chunkedозначает, что ответ отправляется частями; этот метод называется передачей с фрагментированным кодированием. Он используется, когда CouchDB заранее не знает размер отправляемых данных (например, для ленты изменений). -
X-CouchDB-Body-TimeВремя получения тела запроса в миллисекундах.
Доступно, если запрос содержит тело.
-
X-Couch-Request-IDУникальный идентификатор запроса.
Основы JSON
В большинстве запросов и ответов CouchDB для форматирования содержимого и структуры данных используется JavaScript Object Notation (JSON).
JSON используется потому, что это самый простой и удобный способ работы с данными в веб-браузере: структуры JSON можно обрабатывать и использовать как объекты JavaScript в среде веб-браузера. JSON также хорошо сочетается с JavaScript на стороне сервера, используемым в CouchDB.
JSON поддерживает те же основные типы, что и JavaScript:
-
Массив — список значений в квадратных скобках. Например:
["one", "two", "three"]
-
Логическое значение —
trueилиfalse. Эти строки можно использовать напрямую. Например:{ "value": true} Число — целое число или число с плавающей точкой.
-
Объект — набор пар «ключ/значение» (то есть ассоциативный массив или хеш). Ключ должен быть строкой, а значение может иметь любой из поддерживаемых в JSON типов. Например:
{ "servings" : 4, "subtitle" : "Easy to make in advance, and then cook when ready", "cooktime" : 60, "title" : "Chicken Coriander" }В CouchDB объект JSON используется для представления различных структур, включая основной документ CouchDB.
-
Строка — заключается в двойные кавычки и поддерживает символы Unicode и экранирование обратной косой чертой. Например:
"A String"
Преобразование JSON в объект JavaScript поддерживается функцией JSON.parse() в JavaScript, а также различными библиотеками, которые преобразуют содержимое в объект JavaScript. Библиотеки для разбора и создания JSON доступны на многих языках, включая Perl, Python, Ruby, Erlang и другие.
Предупреждение
Следует убедиться, что структуры JSON имеют правильный формат: при обнаружении некорректной структуры CouchDB вернёт код состояния HTTP 500 (ошибка сервера).
Обработка чисел
Разработчики и пользователи, впервые сталкивающиеся с обработкой чисел на компьютере, часто удивляются, обнаруживая, что число, сохранённое в формате JSON, не обязательно возвращается в точности тем же числом при посимвольном сравнении.
Все числа в JSON, содержащие десятичную точку или экспоненту, обрабатываются виртуальной машиной Erlang как значения типа «double». Все числа, используемые в представлениях, обрабатываются сервером представлений как числа (в распространённом случае JavaScript даже целые числа преобразуются в double, поскольку именно так JavaScript определяет число).
Рассмотрим документ, который мы записываем в CouchDB:
{
"_id":"30b3b38cdbd9e3a587de9b8122000cff",
"number": 1.1
} Теперь прочитаем этот документ из CouchDB:
{
"_id":"30b3b38cdbd9e3a587de9b8122000cff",
"_rev":"1-f065cee7c3fd93aa50f6c97acde93030",
"number":1.1000000000000000888
} При этом CouchDB меняет текстовое представление результата декодирования переданного значения на представление в некотором числовом формате. В большинстве случаев это число с плавающей точкой двойной точности IEEE 754, которое используют почти все остальные языки.
Отличие Erlang от других языков заключается в том, что он не пытается красиво вывести результат, используя минимальное число символов. Например, именно поэтому выполняется следующее соотношение:
ejson:encode(ejson:decode(<<"1.1">>)). <<"1.1000000000000000888">>
Может сбить с толку то, что внутри программы оба этих формата декодируются в одно и то же представление IEEE-754. И что ещё важнее, при обработке всеми основными известными нам парсерами они декодируются в достаточно близкое представление.
До сих пор мы рассматривали только случаи изменения текстового представления. Другой важный случай — входное значение содержит больше точности, чем может быть представлено типом double. (Можно утверждать, что в таком случае данные «теряются», если не считать, что числа хранятся в формате double.)
Вот журналы нескольких наиболее распространённых библиотек JSON, установленных на компьютере автора:
Ejson (текущий парсер CouchDB) в CouchDB с sha 168a663b:
$ ./utils/run -i Erlang R14B04 (erts-5.8.5) [source] [64-bit] [smp:2:2] [rq:2] [async-threads:4] [hipe] [kernel-poll:true] Eshell V5.8.5 (abort with ^G) 1> ejson:encode(ejson:decode(<<"1.01234567890123456789012345678901234567890">>)). <<"1.0123456789012346135">> 2> F = ejson:encode(ejson:decode(<<"1.01234567890123456789012345678901234567890">>)). <<"1.0123456789012346135">> 3> ejson:encode(ejson:decode(F)). <<"1.0123456789012346135">>
Node:
$ node -v
v0.6.15
$ node
JSON.stringify(JSON.parse("1.01234567890123456789012345678901234567890"))
'1.0123456789012346'
var f = JSON.stringify(JSON.parse("1.01234567890123456789012345678901234567890"))
undefined
JSON.stringify(JSON.parse(f))
'1.0123456789012346' Python:
$ python
Python 2.7.2 (default, Jun 20 2012, 16:23:33)
[GCC 4.2.1 Compatible Apple Clang 4.0 (tags/Apple/clang-418.0.60)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
import json
json.dumps(json.loads("1.01234567890123456789012345678901234567890"))
'1.0123456789012346'
f = json.dumps(json.loads("1.01234567890123456789012345678901234567890"))
json.dumps(json.loads(f))
'1.0123456789012346' Ruby:
$ irb --version
irb 0.9.5(05/04/13)
require 'JSON'
=> true
JSON.dump(JSON.load("[1.01234567890123456789012345678901234567890]"))
=> "[1.01234567890123]"
f = JSON.dump(JSON.load("[1.01234567890123456789012345678901234567890]"))
=> "[1.01234567890123]"
JSON.dump(JSON.load(f))
=> "[1.01234567890123]" Примечание
Небольшое отступление о Ruby: ему требуется объект или массив верхнего уровня, поэтому я просто обернул значение. Очевидно, что это не влияет на результат разбора числа.
Spidermonkey:
$ js -h 2>&1 | head -n 1
JavaScript-C 1.8.5 2011-03-31
$ js
js> JSON.stringify(JSON.parse("1.01234567890123456789012345678901234567890"))
"1.0123456789012346"
js> var f = JSON.stringify(JSON.parse("1.01234567890123456789012345678901234567890"))
js> JSON.stringify(JSON.parse(f))
"1.0123456789012346" Как видите, все они ведут себя практически одинаково, за исключением Ruby, который, похоже, теряет часть точности по сравнению с другими библиотеками.
Внимательный читатель заметит, что ejson (библиотека JSON CouchDB) вывела ещё три цифры. Может показаться, что это связано с каким-то внутренним различием, но на самом деле это лишь более конкретный вариант входного значения 1.1, описанного выше.
Важно понимать, что double может хранить только конечное число значений. Здесь мы создаём строку, которая при обработке «стандартными» алгоритмами разбора чисел с плавающей точкой (то есть strtod) даст тот же набор битов в памяти, что и исходное значение. Иными словами, байты числа, сериализованного в JSON, выбираются таким образом, чтобы они соответствовали одному конкретному значению, которое может представлять тип double.
Важно понимать, что мы отображаем одно бесконечное множество на конечное. Это легко увидеть, если задуматься над следующим:
1.0 == 1.00 == 1.000 = 1.(infinite zeros)
Очевидно, компьютер не может хранить бесконечное число байтов, поэтому нам приходится сокращать бесконечное множество до конечного, которое можно представить компактно.
Другие библиотеки JSON решают лишь такую задачу:
«Какое минимальное число символов нужно использовать, чтобы выбрать конкретное значение типа double?»
В этой задаче множество тонких нюансов, которые сложно реализовать на C без значительных усилий (Python потребовалось больше года, чтобы разобраться с ней с помощью сложной системы сборки, автоматически запускаемой на нескольких разных архитектурах).
Надеемся, нам удалось показать, что CouchDB не делает ничего «странного», изменяя входные данные. Она работает так же, как любая другая распространённая библиотека JSON, просто не выполняет красивый вывод.
С другой стороны, если вам действительно нужен тип данных для чисел, отличный от double IEEE-754, то, как уже говорилось, не следует передавать числа через это представление. В JSON это можно сделать, закодировав числа как строки или используя целочисленные типы (хотя целочисленные типы тоже могут создать проблемы, если использовать платформу с нестандартным представлением целых чисел, например JavaScript).
Дополнительную информацию можно легко найти, в том числе в руководстве по числам с плавающей точкой и справочнике Дэвида Голдберга.
Кроме того, если кто-то действительно заинтересован в изменении такого поведения, мы будем рады вкладу в jiffy (которая, предположительно, заменит ejson, когда мы обновим систему сборки). В качестве источников вдохновения мы рассматривали TCL и Python. Если вы знаете достойную реализацию этого алгоритма вывода чисел с плавающей точкой, сообщите нам.
Коды состояния HTTP
Поскольку взаимодействие с CouchDB осуществляется через HTTP, коды ошибок и состояния сообщаются с помощью номера кода состояния HTTP и соответствующих данных в теле ответа.
Ниже приведён список кодов ошибок, возвращаемых CouchDB, и общие описания соответствующих ошибок. Значения разных кодов состояния для конкретных типов запросов описаны в соответствующих справочных разделах API.
-
200 - OKЗапрос успешно выполнен.
-
201 - CreatedДокумент успешно создан.
-
202 - AcceptedЗапрос принят, но соответствующая операция могла не завершиться. Этот код используется для фоновых операций, например уплотнения базы данных.
-
304 - Not ModifiedЗапрошенное дополнительное содержимое не изменилось. Этот код используется вместе с системой ETag для определения версии возвращённой информации.
-
400 - Bad RequestНеверная структура запроса. Ошибка может указывать на проблему с URL, путём или заголовками запроса. Различия между указанной MD5-хеш-суммой и содержимым также приводят к этой ошибке, поскольку могут указывать на повреждение сообщения.
-
401 - UnauthorizedЗапрошенный элемент недоступен с указанными данными авторизации или данные авторизации не предоставлены.
-
403 - ForbiddenЗапрошенный элемент или операция запрещены. Возможные причины:
Ваше имя пользователя или роли не соответствуют объекту безопасности базы данных
Для запроса требуются права администратора, которых у вас нет
Вы отправили слишком много запросов с недействительными учётными данными, и ваш доступ временно заблокирован.
-
404 - Not FoundЗапрошенное содержимое не найдено. Если доступна дополнительная информация, она будет включена в ответ в виде объекта JSON. Структура будет содержать два ключа:
errorиreason. Например:{"error":"not_found","reason":"no_db_file"} -
405 - Method Not AllowedЗапрос отправлен с недопустимым типом HTTP-запроса для указанного URL. Например, запрошен
PUT, хотя требуетсяPOST. Ошибки такого типа также могут возникать из-за недопустимых URL. -
406 - Not AcceptableСервер не поддерживает запрошенный тип содержимого.
-
409 - ConflictПри выполнении запроса возник конфликт обновления.
-
412 - Precondition FailedЗаголовки запроса клиента не соответствуют возможностям сервера.
-
413 - Request Entity Too LargeРазмер документа превышает настроенное значение
couchdb/max_document_sizeили размер всего запроса превышает значениеchttpd/max_http_request_size. -
415 - Unsupported Media TypeСписок поддерживаемых типов содержимого и тип содержимого запрошенной или отправляемой информации указывают на то, что этот тип содержимого не поддерживается.
-
416 - Requested Range Not SatisfiableСервер не может выполнить запрос для диапазона, указанного в заголовке.
-
417 - Expectation FailedПри массовой отправке документов операция массовой загрузки завершилась с ошибкой.
-
500 - Internal Server ErrorЗапрос недопустим: либо указанный JSON имеет неверный формат, либо в запросе передана недопустимая информация.
-
503 - Service UnavailableВ данный момент запрос не может быть обработан: возможно, кластер перегружен, выполняются работы по обслуживанию или возникла другая проблема. Запрос можно повторить без изменений, например через несколько минут.
Copyright © 2025 The Apache Software Foundation — Licensed under the Apache License 2.0
https://docs.couchdb.org/en/3.5.1/api/basics.html