Closed jeroenbe closed 8 years ago
Have you tried opening /graphiql on your server and trying to run a query from there?
Just a guess here, but could it be that you're sending the request to the route that's serving graphiql? Unrecognized token '<' kind of suggests that you're getting html, not an empty response. Do you have other queries that work fine?
Since this could be due to a lot of different reasons (error on the server, error on the client, wrong setup, etc.) it would be useful if you could create a repo with a reproduction for us. It sounds like your project is already pretty minimal, so if you can just put that in a github repo it would be fine.
@stubailo Yes, the same fortuneCookie
query runs perfectly fine in GraphiQL.
@helfer It's very likely my setup is just wrong. I'll make a new Repo right away and share it here!
@helfer I just published the project as is to a new remote: https://github.com/JeroenBe/no-response/tree/develop [DELETED] , as you said, its in super early stages anyway ;)
@JeroenBe the problem seems to be with your client configuration. You should use the network interface when creating a client (you created a variable but never used it).
export default client = new ApolloClient({
networkInterface: createNetworkInterface('/graphql', {
credentials: 'same-origin',
}),
shouldBatch: false
});
You need to just direct to the /graphql and not to the full path, but I am not quite sure why... anyone up here can shed some light? (in return to a good the response I will PR the documentation...)
@Tallyb Thanks for the reply!
It didn't really solve the problem though. I placed a screenshot of the ApolloClient
object in my bugreport, as you can see the default _uri
is already defined as "/graphql"
. I tried it with your code nonetheless, but without any results.
Does it work on your end?
@helfer In regards to sending the request to graphiql, here's the code that defines both the graphql and graphiql route:
app.use('/graphql', apolloExpress(req => ({
schema: executableSchema,
context: {
Cookies: new Cookies({connector: fortuneCookieConnector})
},
graphiql: true
})))
app.use('/graphiql', graphiqlExpress({
endpointURL: '/graphql'
}))
The ApolloClient
uses "/graphql"
as its _uri
, as shown in the screenshot of the ApolloClient
object above.
One more thing that I did is install the whatwg-fetch polyfill and import it.
On Sun, Aug 21, 2016, 16:12 Jeroen notifications@github.com wrote:
@helfer https://github.com/helfer In regards to sending the request to graphiql, here's the code that defines both the graphql and graphiql route:
app.use('/graphql', apolloExpress(req => ({ schema: executableSchema, context: { Cookies: new Cookies({connector: fortuneCookieConnector}) }, graphiql: true }))) app.use('/graphiql', graphiqlExpress({ endpointURL: '/graphql' }))
The ApolloClient uses '/graphql' as its uri, as shown in the screenshot of the ApolloClient object above.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/apollostack/apollo-server/issues/103#issuecomment-241256567, or mute the thread https://github.com/notifications/unsubscribe-auth/AHC0j3LZHxyYEuBDpytlWMpds9pVf2Iyks5qiE7QgaJpZM4JpLJ4 .
@Tallyb Could you show me how you're using whatwg-fetch
? I'm not sure what to do with it :s
npm install --save whatwg-fetch
on your client definition file (client.js)
import 'whatwg-fetch';
Did you notice that on my example above I removed the localhost:4000
from the client definition?
Ok, so I installed whatwg-fetch
(and what
since it's a peer dependency) and importing it, but I still receive the same error. If the code works on your end, would you mind making a PR to the repo I shared? (https://github.com/JeroenBe/no-response/tree/develop [DELETED])
This is how my client
looks like at the moment:
export default client = new ApolloClient({
networkInterface: createNetworkInterface('/graphql', {
credentials: 'same-origin',
}),
shouldBatch: false
})
It looks like your request is going to the meteor server instead of the GraphQL server. Install the http-proxy-middleware
package from npm and add these two lines somewhere in your server startup code:
import proxyMiddleware from 'http-proxy-middleware';
WebApp.rawConnectHandlers.use(proxyMiddleware('http://localhost:4000/graphql'));
having the same problem. graphiql is working but not my front-end query. repo: https://github.com/jktunney/newgivefit/tree/apollo
ok - here is what I did: on client.js:
export default client = new ApolloClient({
networkInterface: createNetworkInterface('//localhost:4000/graphql', {
credentials: 'same-origin',
}),
shouldBatch: false
});
Then I added cors support as described in the docs: http://docs.apollostack.com/apollo-server/tools.html#corsSupport
so server js now has:
import cors from 'cors';
const app = express().use('*', cors());
Need also npm install cors
of course (pun-intended)
@helfer @Tallyb Yes! Both solutions are working!
Could you elaborate as to why these are working and which one is best practice?
Thanks btw!
You were simply sending the query to the wrong server. The GraphQL server is on port 4000, but you sent the query to port 3000, which is the Meteor server. You can either directly call the GraphQl server (CORS) or proxy through the Meteor server. Either is fine, and it probably doesn't matter for your setup.
By the way, with the new Apollo Server you can use it with connect
directly, no proxy required.
@stubailo Do you mean by using the cors
package as suggested by @Tallyb?
No I'm saying you can do WebApp.connectHandlers.use('/graphql', apolloExpress(...))
and then no cors
required.
@stubailo but using connect will still redirect calls to GraphQL server via the meteor server, which can impact load and performance, right?
Oke, so now I have the following code in my server.js
file:
const app = express() //running on port 4000
// ...
WebApp.connectHandlers.use('/graphql', apolloExpress(req => ({
schema: executableSchema,
context: {
Cookies: new Cookies({connector: new FortuneCookieConnector()})
},
graphiql: true
})))
In stead of:
app.use('/graphql', apolloExpress(req => ({
schema: executableSchema,
context: {
Cookies: new Cookies({connector: new FortuneCookieConnector()})
},
graphiql: true
})))
this gives me Cannot POST /graphql?
on GraphiQL, when I define GraphiQL in the same way:
WebApp.connectHandlers.use('/graphiql', graphiqlExpress({
endpointURL: '/graphql'
}))
I get following error when requesting GraphiQL: Cannot GET /graphiql
I'm guessing I have to reference the location of the actual express server, where would I do this?
You shouldn't need express
at all anymore - I'll look into this more soon.
@stubailo Yes! I removed all references to express
which did the trick!
Thanks everyone for the responses! @stubailo @helfer @Tallyb
Oh, glad it worked out!
@Tallyb just saw your comment - I can't think of any reason this would have a performance disadvantage compared to using something else.
@stubailo my thought is that if you go via meteor server, it needs to handle your request and then redirect it to the Apollo Server, while using the direct access to the Apollo Server, does not require the Meteor Server to handle it at all. If they are on different machines, and with high load of users, it can be significant. Am I missing something here?
@JeroenBe can you post your solution? i'm having a similar issue and it would be much appreciated. thanks!
@jktunney Yea of course!
In the end I went with @stubailo's solution. In my server.js
I removed all express
references/dependencies. and replaced it with WebApp.connectHandlers
, e.g.:
import express from 'express'
const app = express()
app.use(bodyParser.json())
app.use('/graphql', new ApolloExpress( ... ))
// ... etc etc etc
became:
WebApp.connectHandlers.use(bodyParser.json())
WebApp.connectHandlers.use('/graphql', new ApolloExpress( ... ))
// ...
And on the client, my client
is defined as such:
import ApolloClient from 'apollo-client'
export default client = new ApolloClient();
The problem in my case was the graphql requests being sent to the meteor server, not the express or graphql server. Meteor doesn't know what to do with them, hence the error. Obviously there are multiple ways of solving this (I listed them up in my initial post).
Hope this helps!
ok, i'm still not getting it. i'm using node and express however...
here is my server:
var webpack = require('webpack');
var WebpackDevServer = require('webpack-dev-server');
var express = require('express');
var graphql = require('graphql');
var graphqlTools = require('graphql-tools');
var apollo = require('apollo-server');
var apolloExpress = apollo.apolloExpress;
var graphiqlExpress = apollo.graphiqlExpress;
var bodyParser = require('body-parser')
var proxyMiddleware = require('http-proxy-middleware');
var cors = require('cors');
//Material UI
global.navigator = { navigator: 'all' };
var schema = require('./app/data/schema');
var compiler = require('./webpack.config');
//GraphQL Stuff
var PORT = 8080;
var graphqlServer = express();
graphqlServer.use('/graphql', bodyParser.json(), new apolloExpress({
schema: schema
}));
graphqlServer.use('/graphiql', graphiqlExpress({
endpointURL: '/graphql',
}));
graphqlServer.listen(PORT, () => console.log(
`GraphQL Server is now running on http://localhost:${PORT}/graphql`
));
var app = new WebpackDevServer(compiler, {
contentBase: "/public/",
publicPath: "/static/",
stats: {colors: true}
});
app.use(proxyMiddleware('http://localhost:3010/graphql'));
app.use("/", express.static("static"));
app.listen(3000);
console.log("The App Server is running.")
here is my client `import React from 'react':
import { render } from 'react-dom';
import { browserHistory, IndexRoute, Router, Route } from 'react-router';
//Redux stuff
import thunkMiddleware from "redux-thunk";
import { Provider } from 'react-redux';
import { bindActionCreators, createStore, applyMiddleware } from 'redux';
//Local imports
import { queryReducer } from './reducers/reducer';
import routes from './config/routes';
import configStore from './store/configStore';
//Material UI qualms
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import injectTapEventPlugin from "react-tap-event-plugin";
import ApolloClient, { createNetworkInterface, addTypename } from 'apollo-client'
import { ApolloProvider } from 'react-apollo'
injectTapEventPlugin();
//Create store middleware
/*const createStoreWithMiddleware = applyMiddleware(thunkMiddleware)(createStore);*/
const client = new ApolloClient({
networkInterface: createNetworkInterface('localhost:8080/graphql', {
credentials: 'same-origin',
}),
shouldBatch: false
})
console.log("client");
console.log(client);
console.log("client");
const Application = () => (
<MuiThemeProvider>
<Router
history={browserHistory}
routes={routes}
/>
</MuiThemeProvider>
);
render(
<ApolloProvider client={client}>
<Application />
</ApolloProvider>,
document.getElementById('app')
);
here is my react component with my apollo query:
import React, { Component } from 'react';
import { graphql } from 'react-apollo';
import gql from 'graphql-tag';
import GridComponent from './GridComponent';
class GridContainer extends React.Component {
render() {
console.log("props")
console.log(this.props)
const workouts = this.props.data.workouts;
return (
<GridComponent workouts={workouts} />
)
}
};
const GET_WORKOUTS = gql`
query getWorkouts {
workouts { title, date, time, location, author, contentSnippet, tags, day, image, avatar, id }
}
`;
const withWorkouts = graphql(GET_WORKOUTS);
const GridContainerWithData = withWorkouts(GridContainer)
export default GridContainerWithData;
graphiql is working:
when i go to my graphql route in my browser it returns:
when i navigate to my route that renders the GridContainerWithData it shows this error in the console:
i've tried all the different solutions above, barring using connectHandlers (not using Meteor)... very frustrated because it seems like it should be a simple solution. i'd appreciate any help!
@jktunney could you commit your latest changes to your repo? I cloned it but it seems the repo you have online is not up to date with the code you shared here.
@JeroenBe the repo should be updated at this branch: https://github.com/jktunney/newgivefit/tree/apollo
@jktunney Ok, so after running the project and logging the actual error it throws, it seems the error you receive is slightly different than the one I got:
"Network error: JSON Parse error: Unexpected identifier \"Cannot\""
I'm not sure if your problem is caused by the same issue as mine
@JeroenBe how were you able to produce that error?
@jktunney the error
field is part of your response. One the first render the error
field is obviously undefined
since the query is still loading: true
. When loading: false
or loading: undefined
(in case of an error), the component will rerender.
on this line, you try to access your workouts
, but since the query failed with an error you get thrown an exception. I removed this line and in stead logged this.props.data.error
.
very strange... when i swap this
class GridContainer extends React.Component {
render() {
console.log("props")
console.log(this.props)
const workouts = this.props.data.workouts;
return (
<GridComponent workouts={workouts} />
)
}
};
for this:
class GridContainer extends React.Component {
constructor(props) {
super(props)
}
render() {
console.log("props")
console.log(this.props)
const workouts = this.props.data.workouts;
console.log("workouts")
console.log(workouts)
return (
<div>
hello world
</div>
)
}
};
i get:
but when i try to pass "workouts" to my GridComponent component, I get:
I'm concerned that this thread might be related to several different issues at this point.
Empty response on graphql request
When sending a graphql
POST
request to theapollo-server
, I receive nothing but an empty response.Context
Since this is my first ever project using Apollo (trying to set it up with Meteor, React, apollo-client and apollo-server using express), I'm just trying to connect a front end with the Fortunecookie api.
This is what I figured out so far:
"Can't find field fortuneCookie on object (ROOT_QUERY) {}.↵Perhaps you want to use the 'returnPartialData' option?"
. When I went looking for this in the Redux Devtool, I found myquery
as such:Which gave nothing in response.
Setup
Since the task I want to complete is fairly simple, my setup is too. The query I want to execute runs perfectly fine on GraphiQL, which leads me to believe my server is running as it should.
ApolloProvider
Child Component
The
{content}
child set in the<ApolloProvider />
is the<TestComponent />
displayed below. This is set using kadira'sFlowRouter
andreact-mounter
, nothing special there.Extra Screenshots
During a conversation on the apollo slack channel, I took some screenshots. They might provide some extra insights. The
ApolloClient
object:The
HTTP request
(response is empty):First an
APOLLO_QUERY_INIT
action is stored:Next an
APOLLO_QUERY_ERROR
action:I hope I provided enough information. Please bare with me that chances are my setup is just wrong and there is nothing funky going on with the apollo stack. This is my first project after all.
EDIT: I realise I said my server seems to be running fine, but because there isn't any response returned from my request I thought this issue belonged in the
apollo-server
repo.SOLUTION: Turned out the graphql requests were sent to the meteor server in stead of the express server. There are a few solutions to this problem (listed below in the comments). You could connect directly to the express server using
cors
or the ApolloServer 'WebApp.connectHandlers.use(...)' or setup a proxy that redirects calls usinghttp-proxy-middleware
.