Преобразование полезной нагрузки из requestjs перед отправкой клиенту

Братья и сестры, я создаю конечную точку Express API, которая должна использовать внешний API, выполнять некоторые изменения ключей и значений и возвращать результат клиенту. Вот что у меня есть на данный момент:

const external_endpoint = <external_api_end_point>;

app.get('/', function (req, res, next) {

  request({ url: external_endpoint}).pipe(res);
});

Это возвращает точную полезную нагрузку, которую вы получите от прямого попадания в external_endpoint.

Есть ли что-то, что я могу сделать, чтобы изменить res до того, как он будет отправлен клиенту? Я пробовал несколько вещей, но ничего не помогло. Есть какие-нибудь идеи или лучшие практики, связанные с преобразованием входящей полезной нагрузки?

Ради простоты. Допустим, это полезная нагрузка obj.json:

{
    "sad": {
        "userid": 5,
        "username": "jsmith",
        "isAdmin": true
    }
}

и я хочу заменить sad на happy.

Я знаю, что вне запроса я мог бы сделать что-то вроде этого:

obj = JSON.parse(JSON.stringify(obj).split('"sad":').join('"happy":'));

но бросить obj вместо res не получится. Я попытался присвоить значение этим res и res.body, но без игральных костей.

Заранее благодарим за помощь!

Можете уточнить, что такое request? Это может быть несколько библиотек.

Jim B. 24.11.2018 16:57

правильно. Извините, что не прояснил это. Я использую request ^2.88.0. Вот ссылка на репозиторий github для него github.com/request/request

Matthew McGuff 25.11.2018 04:52

Понятно. Да, базовый модуль request обрабатывает потоковую передачу для выражения ответов как первоклассный гражданин. Итак, вы можете использовать метод event-stream, который я описываю в ответе.

Jim B. 25.11.2018 06:39
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
3
61
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Если вы используете request-promise, вы можете просто создать новый ответ и отправить его или изменить полученный ответ:

app.get('/', function (req, res, next) {    
    request({ url: external_endpoint, json: true})
        .then(response => res.json({ happy: response.sad })))
        .catch(next);
});

(конечно, вам нужно правильно обрабатывать ошибки)

Если вы хотите обрабатывать его как поток (что имеет смысл, если у вас большой объем данных), вы можете использовать исходный модуль request и использовать event-stream для создания своего канала:

const es = require('event-stream');

const swapper = es.through(
    function write(data) {
        this.emit("data", data.replace("sad", "happy"));
    },
    function end() {
        this.emit("end");
    }
);

request({ url: external_endpoint})
    .pipe(es.stringify())
    .pipe(swapper)
    .pipe(es.parse())
    .pipe(res);

Вот песочница для тестирования потоковой обработки: https://codesandbox.io/s/3wqx67pq6

В приведенном выше коде с использованием await вам нужно добавить async непосредственно перед функцией, иначе await вернется как undefined.

Matthew McGuff 25.11.2018 16:22

Таким образом, на .pipe(es.map(j => j.replace('sad', 'happy')) может показаться, что нам не хватает закрывающего ). Однако даже когда я добавляю это в конец строки, он работает не так, как ожидалось. Я попытался добавить в конец .pipe(res)), он возвращает полезную нагрузку, но без какой-либо замены.

Matthew McGuff 25.11.2018 17:19

В самом деле, es.map() неправильный, потому что в этот момент мы получаем строку. Заменен на es.through()

Jim B. 25.11.2018 17:34

Кстати, были проблемы со ссылкой на коды и ящик, но я думаю, что теперь она работает.

Jim B. 25.11.2018 18:09

Замечательно, но хочется сделать это немного лучше. Скажем, у кого-то есть слово sad в имени пользователя (или в любом другом значении, если на то пошло). Как предотвратить или гарантировать, что .replace не изменит это значение? Я попытался заменить data.replace("sad", "happy") на data.replace('"sad":', '"happy":'), но включение кавычек, похоже, нарушает работу замены. Любые идеи о том, как я могу настроить таргетинг только на изменение ключей вместо данных? До сих пор вы оказали огромную помощь. Спасибо за все.

Matthew McGuff 26.11.2018 14:42

Просто ответил на мои вопросы. .replace поддерживает использование регулярных выражений. Это означает, что я могу использовать регулярное выражение, что-то вроде И, чтобы еще больше убедиться, что я не заменяю то, что я не собираюсь, я могу использовать регулярное выражение, поскольку кажется, что .replace поддерживает использование регулярных выражений. Однако при тестировании с чем-то вроде "sad": или даже /"user":/. Его не удается заменить, хотя я уверен, что мое регулярное выражение верное. Есть идеи по этому поводу?

Matthew McGuff 26.11.2018 15:07

Может быть тема для другого вопроса. Регулярные выражения мощные, но непростые. Я рекомендую разбить его и использовать узел в режиме REPL для отладки.

Jim B. 26.11.2018 16:17

согласованный. Вот почему я пометил это как ответ. Еще раз спасибо!

Matthew McGuff 26.11.2018 21:43

Другие вопросы по теме