Как сделать, чтобы запрос ORDS возвращал JSON_OBJECT без кавычек? - PullRequest
0 голосов
/ 25 февраля 2020

Я пытаюсь создать JSON для возврата в результате HTTP GET с использованием ORDS на Oracle База данных XE 18 c. Используя JSON_OBJECT и аналогичные функции, SELECT, кажется, всегда окружает результирующие JSON кавычками и экранирует кавычки внутри объекта. Пример:

CREATE TABLE test_cases (
    team VARCHAR2(3),
    response_time NUMBER
);

INSERT INTO test_cases (team, response_time) VALUES ('foo', 1);
INSERT INTO test_cases (team, response_time) VALUES ('foo', 2);
INSERT INTO test_cases (team, response_time) VALUES ('foo', 5);
INSERT INTO test_cases (team, response_time) VALUES ('bar', 5);
INSERT INTO test_cases (team, response_time) VALUES ('bar', 7);
INSERT INTO test_cases (team, response_time) VALUES ('bar', 9);
COMMIT;

BEGIN
  ORDS.define_module(
    p_module_name    => 'rest',
    p_base_path      => 'rest/',
    p_items_per_page => 0
  );

  ORDS.define_template(
    p_module_name    => 'rest',
    p_pattern        => 'stats/'
  );

  ORDS.define_handler(
    p_module_name    => 'rest',
    p_pattern        => 'stats/',
    p_method         => 'GET',
    p_source_type    => ORDS.source_type_query_one_row,
    p_source         => '
SELECT JSON_OBJECTAGG (
    KEY t.team VALUE AVG(t.response_time)
)
AS averages
FROM test_cases t 
GROUP BY t.team 
                        ',
    p_items_per_page => 0
  );

  COMMIT;
END;
/

Запрос ресурса дает следующий результат:

$ curl -i -H "Content-Type: application/json" -X GET "http://localhost:8080/ords/rest/stats/"
HTTP/1.1 200 OK
Content-Type: application/json
{"averages":"{\"foo\":2.66666666666666666666666666666666666667,\"bar\":7}"}

, где указывается значение JSON «среднего». Поведение, по-видимому, является специфическим для JSON_OBJECT, потому что другие вызовы SELECT, использующие те же параметры ORDS, не добавляют кавычки к результатам.

Есть ли способ отменить вывод JSON_OBJECT перед его преобразованием в результат из SELECT?

1 Ответ

1 голос
/ 27 февраля 2020

Поскольку вы сами генерируете JSON, вы хотите изменить SOURCE_TYPE на Media Resource. Затем в вашем запросе в первом столбце будет указан тип MIME, поэтому ваш браузер знает, как обрабатывать входящие двоичные данные.

Попробуйте это -

BEGIN
  ORDS.DEFINE_HANDLER(
      p_module_name    => 'rest',
      p_pattern        => 'stats/',
      p_method         => 'GET',
      p_source_type    => 'resource/lob',
      p_items_per_page =>  0,
      p_mimes_allowed  => '',
      p_comments       => NULL,
      p_source         => 
'SELECT ''application/json'', JSON_OBJECTAGG (
    KEY t.team VALUE AVG(t.response_time)
)
AS averages
FROM test_cases t 
GROUP BY t.team '
      );

  COMMIT; 
END;
/

Затем я вызываю GET в мой браузер -

enter image description here

{
"foo": 2.6666666666666665,
"bar": 7
}

Теперь, допустим, у вас также есть некоторые обычные данные, но только ОДИН из столбцов хранится JSON в или сгенерированный БД - вы хотите, чтобы ORDS JSON - уточнил ваши обычные данные, но не данные, которые УЖЕ json.

Есть способ получить свой торт и съесть его тоже, на серебряная ложка.

BEGIN
  ORDS.DEFINE_HANDLER(
      p_module_name    => 'rest',
      p_pattern        => 'stats/',
      p_method         => 'GET',
      p_source_type    => 'json/collection',
      p_items_per_page =>  0,
      p_mimes_allowed  => '',
      p_comments       => NULL,
      p_source         => 
'SELECT JSON_OBJECTAGG (
    KEY t.team VALUE AVG(t.response_time)
)
"{}jsons"
FROM test_cases t 
GROUP BY t.team '
      );

  COMMIT; 
END;
/

Для ваших JSON данных добавьте этот столбец псевдоним

"{}jsons"

Запуск теперь выглядит так -

enter image description here

...