graphql-framework-experiment icon indicating copy to clipboard operation
graphql-framework-experiment copied to clipboard

bodyParser breaks graphql server

Open gustawdaniel opened this issue 5 years ago • 3 comments

I have code

import {server} from 'nexus'

const app = server.express
const p = require('../package.json')

app.get('/version', async (req, res) => {
    res.send({version: p.version})
})

And tests

import {expect} from 'chai'
import axios from 'axios';

const HOST = 'http://localhost:4000';

describe('Server', () => {
    it('graphql should work', async () => {
        const {data, status} = await axios.post(HOST + '/graphql', {
            query: '{ ok }'
        })
        expect(status).equal(200)
        expect(data).to.eql({ data: { ok: true } });
    })


    it('express should work', async () => {
        const {data, status} = await axios.get(HOST + '/version')
        expect(status).equal(200)
        expect(data).has.key('version');
    })
})

It works. But when I am adding bodyParser to make possible uploading files

const bodyParser = require('body-parser')
app.use(bodyParser.raw({type: 'application/octet-stream', limit: '50mb'}))

so my file looks like this:

import {server} from 'nexus'

const app = server.express
const p = require('../package.json')

const bodyParser = require('body-parser')
app.use(bodyParser.raw({type: 'application/octet-stream', limit: '50mb'}))


app.get('/version', async (req, res) => {
    res.send({version: p.version})
})

then

my test are broken

  Server
    1) graphql should work
    ✓ express should work


  1 passing (48ms)
  1 failing

  1) Server
       graphql should work:
     Error: Request failed with status code 400
      at createError (node_modules/axios/lib/core/createError.js:16:15)
      at settle (node_modules/axios/lib/core/settle.js:17:12)
      at IncomingMessage.handleStreamEnd (node_modules/axios/lib/adapters/http.js:236:11)
      at endReadableNT (_stream_readable.js:1185:12)
      at processTicksAndRejections (internal/process/task_queues.js:81:21)

and I can see error:

7480 ■ nexus:server:graphql BadRequestError: request.body json expected to have a query field
    at /home/daniel/pro/ocr/backend/node_modules/nexus/dist/runtime/server/handler-graphql.js:21:60
    at async /home/daniel/pro/ocr/backend/node_modules/nexus/dist/runtime/server/server.js:98:9

gustawdaniel avatar Jun 04 '20 16:06 gustawdaniel

To fix you need add line

app.use(bodyParser.json({type: 'application/json'}))

but nothing about this case in docs is mentioned. I propose to add to docs section about connecting bodyParser with nexus-graphql.

gustawdaniel avatar Jun 04 '20 16:06 gustawdaniel

For now, a brief mention about customizing server body parsing could go into the server docs section. PR welcome. Can start very simple.

jasonkuhrt avatar Jun 10 '20 02:06 jasonkuhrt

Running in to the same issue, it's my understanding that when using body-parser you should be able to specify the Content-Type you'd like to have filtered by the body parser middleware. For example, I need to parse a body of type application/octet-stream from Google Cloud Tasks that is attempting to hit my Nexus api. However, when I add the following in my app.ts to accept octet-stream:

server.express.use(bodyParser.raw({type: 'application/octet-stream'}));

I receive the following error when trying to send any kind of request (even from graphql playground):

■ nexus:server:graphql BadRequestError: request.body json expected to have a query field
    at /Users/jordan/GitHub/releasehub-app/server/node_modules/nexus/dist/runtime/server/handler-graphql.js:21:60
    at processTicksAndRejections (internal/process/task_queues.js:97:5)
    at async /Users/jordan/GitHub/releasehub-app/server/node_modules/nexus/dist/runtime/server/server.js:101:9

But if I add in:

server.express.use(bodyParser.json());

beneath this .raw() then things work as normal. Seems like odd behavior.

uncvrd avatar Jul 31 '20 06:07 uncvrd