prisma-labs / graphql-framework-experiment

Code-First Type-Safe GraphQL Framework
https://nexusjs.org
MIT License
675 stars 66 forks source link

bodyParser breaks graphql server #970

Open gustawdaniel opened 4 years ago

gustawdaniel commented 4 years ago

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 commented 4 years ago

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.

jasonkuhrt commented 4 years ago

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

uncvrd commented 3 years ago

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.