Apollo Server 2 + Express: в обработчике сообщений отсутствует req.body

Если бы это работало в версии 1, но вся конфигурация сервера изменилась. Это то, что у меня есть после добавления bodyparser() в экспресс-приложение, как было предложено Даниэлем в комментариях:

    const server = new ApolloServer({
    typeDefs,
    resolvers,
    playground: {
        settings: {
            'editor.theme': 'light',
        }
    },
})

// Initialize the app
const app = express();
app.use(cors())
app.use(bodyParser.json())

server.applyMiddleware({
    app
})

app.post('/calc', function(req, res){
    const {body} = req;

    console.log("HOWDYHOWDYHOWDY", body) // <== body is {}

    res.setHeader('content-type', 'application/json')

    calculate(body)
        .then(result => res.send(result))
        .catch(e => res.status(400).send({error: e.toString()}))    
})

Тело запроса никогда не доходит до обработчика app.post, хотя обработчик вызывается. Однако я вижу, что он выходит из браузера. Любые идеи?

Обновление: у Дэниела был правильный ответ, но у меня была другая проблема в заголовках запросов, которые я использовал. Как только я это исправил, обработчик сообщения получил тело.


person Jeff Lowery    schedule 11.10.2018    source источник


Ответы (2)


Промежуточное ПО Apollo применяет промежуточное ПО bodyparser специально к конечной точке GraphQL — это не повлияет на другие маршруты, предоставляемые вашим сервером. Чтобы правильно заполнить req.body, вам нужно самостоятельно добавить промежуточное ПО bodyparser, например:

app.use(bodyParser.json())
app.post('/calc', routeHandler)

// or...
app.post('/calc', bodyParser.json(), routeHandler)
person Daniel Rearden    schedule 11.10.2018
comment
Я ценю ваш ответ, Дэниел. Я сделал то, что вы предложили, и обновлю свой исходный пост. Теперь я получаю пустой объект JSON вместо неопределенного. Лучше? Поэтому я немного удивлен, что req.body будет пустым без промежуточного программного обеспечения bodyparser, прикрепленного к приложению - я ожидаю текстовое тело. Без bodyparser.json() = undefined; с = {} - person Jeff Lowery; 11.10.2018
comment
req.body по умолчанию не определен (см. экспресс-документы: expressjs.com/en/ 4x/api.html#req.body) В зависимости от того, что вы отправляете, вам может потребоваться выбрать соответствующий синтаксический анализатор, чтобы правильно заполнить тело сообщения. Подробнее см. этот ответ (stackoverflow.com/a/47486182/6024220) и документы body-parser. Также имейте в виду, что если вы используете составные тела, вам понадобится другая библиотека, такая как multer. - person Daniel Rearden; 11.10.2018
comment
Ладно, кое-что узнал. Я звоню правильному парсеру тела, так что проблема не в этом. У других людей похожие проблемы, кажется. Не могу найти прямого следствия того, что я пытаюсь здесь сделать, но когда я найду ответ, я опубликую его. - person Jeff Lowery; 11.10.2018
comment
Вы также можете просто попробовать переместить свой маршрут /calc выше вашего вызова applyMiddleware, чтобы он вызывался и завершался до того, как apollo сделает что-нибудь по вашему запросу. - person Daniel Rearden; 11.10.2018
comment
да, пробовал, безрезультатно. НО... оказывается, у меня была ошибка с заголовками запроса в моем клиентском коде (строка, которую я забыл удалить), так что это была вторая проблема. Теперь, где бы ни находился обработчик сообщений, я вижу тело (наконец-то!). Пометка вашего ответа как ответа. Спасибо еще раз. - person Jeff Lowery; 11.10.2018

Я просто столкнулся с этим. Исправил, передав в заголовки следующее:

Content-Type: application/json
person ha404    schedule 30.03.2019