Spec-Zone.ru › CouchDB 3.5

Основы 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

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API