Избегайте преобразования некоторых значений в JSON с помощью groovy HTTPBuilder/RESTClient.

Я пытаюсь использовать RESTClient groovy для добавления проектного документа в базу данных CouchDB. CouchDB требует, чтобы функции в проектном документе (например, функции map/reduce в представлениях) были строками, а не фактическими объектами JSON Function. К сожалению, HTTPBuilder автоматически преобразует строку в JSON Function вместо того, чтобы сохранять ее как String. Вот простой пример:

import groovyx.net.http.ContentType
import groovyx.net.http.RESTClient

RESTClient restClient = new RESTClient('http://localhost:5984', ContentType.JSON)
def databaseName = 'sampledb'
restClient.put path: "/${databaseName}" // Create the sample DB

def document = [
  language: 'javascript',
  views: [
    sample_view: [
      map: 'function(doc) { emit(doc._id, doc); }'
    ]
  ]
]
// CouchDB returns 400 Bad Request at the following line
restClient.put path: "/${databaseName}/_design/sample_design", body: document

Вот соответствующая часть журнала CouchDB (обратите внимание, что функция map не заключена в кавычки):

[Fri, 17 Mar 2017 16:32:49 GMT] [error] [<0.18637.0>] attempted upload of invalid JSON (set log_level to debug to log it)
[Fri, 17 Mar 2017 16:32:49 GMT] [debug] [<0.18637.0>] Invalid JSON: {{error,
                                      {56,
                                       "lexical error: invalid string in json text.\n"}},
                                     <<"{\"language\":\"javascript\",\"views\":{\"sample_view\":{\"map\":function(doc) { emit(doc._id, doc); }}}}">>}
[Fri, 17 Mar 2017 16:32:49 GMT] [info] [<0.18637.0>] 127.0.0.1 - - PUT /sampledb/_design/sample_design 400
[Fri, 17 Mar 2017 16:32:49 GMT] [debug] [<0.18637.0>] httpd 400 error response:
 {"error":"bad_request","reason":"invalid_json"}

Я пробовал вставлять кавычки в строку (т.е. map: '"function(doc) { emit(doc._id, doc); }"'; это сохраняет значение в виде строки, но также сохраняет встроенные кавычки, что не позволяет CouchDB выполнять функцию. Кто-нибудь знает, как я могу сохранить определенные значения в виде простых строк во время преобразование в JSON?


person CarLuva    schedule 17.03.2017    source источник


Ответы (1)


В конце концов я нашел ответ на свой вопрос. Простое решение, которое ускользало от меня около года, состоит в том, чтобы определить дизайн-документ как String, а не как Map. Следующая небольшая модификация примера сценария в вопросе работает по назначению:

import groovyx.net.http.ContentType
import groovyx.net.http.RESTClient

RESTClient restClient = new RESTClient('http://localhost:5984', ContentType.JSON)
def databaseName = 'sampledb'
restClient.put path: "/${databaseName}" // Create the sample DB

def document = /
{
  "language": "javascript",
  "views": {
    "sample_view": {
      "map": "function(doc) { emit(doc._id, doc); }"
    }
  }
}
/
// CouchDB no longer returns 400 Bad Request at the following line and now correctly parses the
// design document!
restClient.put path: "/${databaseName}/_design/sample_design", body: document
person CarLuva    schedule 20.02.2019