error: Response not successful: Received status code 400" Graphql - graphql

what i wanted to do is to separate my schema from the index.js file. so here are the index.js file and schema.js file after separation.
//schema.js
import { gql, makeExecutableSchema } from 'apollo-server-express';
const typeDefs = gql`
type Query {
hello : String
}
`;
const resolvers = {
Query:{
hello: () => 'HelloWorld!'
}
};
export default makeExecutableSchema({
typeDefs,
resolvers,
});
//index.js
import { ApolloServer } from 'apollo-server-express';
import express from 'express';
const schema = require('./schema');
const app = express();
const server = new ApolloServer({schema});
server.applyMiddleware({app});
app.listen(4000, ()=> {
console.log(`app is working on port 4000 ${server.graphqlPath}`);
});
i still can open graphql playground on localhost:4000/graphql
but after the separation i receive the following error.

I replaced the line const schema = require('./schema'); to import schema from './schema'; solved my problem.
even though I am using node V8.10 I used the babel compiler to use modern syntax with node. the old syntax was the issue.

Related

Migrating to 3.5.0 with apollo-server-express

I'm trying to update the version of one of my projects from node 12.x.x to node.14.x.x.
Now I saw the documentation of apollo to migrate to the v3 but it's not clear at all someone know where to start? Is it gonna be easier to make all the apollo part systems from scratch?
Current file that should be updated:
const { ApolloServer } = require('apollo-server-express');
const { makeExecutableSchema } = require('graphql-tools');
const { applyMiddleware } = require('graphql-middleware');
const { gql } = require('apollo-server-express');
const { resolvers, typeDefs } = require('graphql-scalars');
const { types } = require('./typedefs/types');
const { inputs } = require('./typedefs/inputs');
const { queries } = require('./typedefs/queries');
const { mutations } = require('./typedefs/mutations');
const customResolvers = require('./resolvers');
const { permissions } = require('./permissions/permissions');
const graphqlApis = gql`
${types}
${queries}
${inputs}
${mutations}
`;
const schema = makeExecutableSchema({
typeDefs: [...typeDefs, graphqlApis],
resolvers: {
...customResolvers,
...resolvers,
},
});
const server = new ApolloServer({
context: ({ req }) => {
const headers = req.headers || '';
return headers;
},
schema: applyMiddleware(schema, permissions),
});
module.exports = server;
Current error when trying to run: Error: You must 'await server.start()' before calling 'server.applyMiddleware()'
I would simply love to get some solutions/help/insight with it.
As mentioned in the docs, you need to surround your code with an Async function
https://www.apollographql.com/docs/apollo-server/migration/
(async function () {
// ....
})();
Or Like so: ...
define your typeDefs & resolvers first
const typeDefs = "" // your typedefs here
const resolvers = "" // your resolvers here
async function startApolloServer(typeDefs, resolvers) {
// Apollo Express 3.5.x code goes here
// ....
await server.start();
// promise resolve...
}
startApolloServer(typeDefs, resolvers)

Apollo graphql subscriptions, using the same endpoint for the graphql server and websocket endpoint

I was just wondering if there was any performance decrease or any disadvantage in using the same endpoint for the graphql endpoint and also for the WebSocket. You can see the sample code below.
import express = require("express");
import { ApolloServer } from "apollo-server-express";
import bodyParser from "body-parser";
import Knex from "knex";
import { execute, subscribe } from "graphql";
import { SubscriptionServer } from "subscriptions-transport-ws";
// graphql api
import api from "./api";
const { createServer } = require("http");
const app: express.Application = express();
const path = "/graphql";
app.use(bodyParser.json());
const graphqlServer = new ApolloServer(api);
graphqlServer.applyMiddleware({ app, path });
const server = createServer(app);
server.listen(process.env.PORT, err => {
if (err) {
throw new Error(err);
}
new SubscriptionServer(
{
execute,
subscribe,
schema: api.schema
},
{
server,
// same as the graphql endpoint
path
}
);
console.log(
`the server is running at http://localhost:${process.env.PORT}/graphql`
);
});

local state management for graphql vue apollo

I am trying to make local state management with vue apollo, but even after following the docs I am getting no result. There is no error in the console so I am not sure what is wrong.
Here is my setup:
// main.js file the initializing part
const client = new ApolloClient({
link: ApolloLink.from([
errorLink,
authMiddleware,
link,
]),
cache,
typeDefs,
resolvers,
connectToDevTools: true,
});
// resolvers file
import gql from 'graphql-tag';
import { todoItemsQuery } from './task.queries';
export const typeDefs = gql`
type Item {
id: ID!
text: String!
done: Boolean!
}
type Mutation {
changeItem(id: ID!): Boolean
deleteItem(id: ID!): Boolean
addItem(text: String!): Item
}
`;
export const resolvers = {
Mutation: {
checkItem: (_, { id }, { cache }) => {
const data = cache.readQuery({ query: todoItemsQuery });
console.log('data res', data);
const currentItem = data.todoItems.find(item => item.id === id);
currentItem.done = !currentItem.done;
cache.writeQuery({ query: todoItemsQuery, data });
return currentItem.done;
},
},
};
//queries file
import gql from 'graphql-tag';
export const todoItemsQuery = gql`
{
todoItems #client {
id
text
done
}
}
`;
export const checkItemMutation = gql`
mutation($id: ID!) {
checkItem(id: $id) #client
}
`;
// component where I call it
apollo: {
todoItems: {
query: todoItemsQuery
}
},
checkItem(id) {
this.$apollo
.mutate({
mutation: checkItemMutation,
variables: { id }
})
.then(({ data }) => {
console.log("CACHE", data);
});
},
I get empty todoItems, no errors.
Please let me know what am I missing, I am not grasping some concept I think, and if there is a way to use vuex with apollo then I can do that too.
Foreword: I'm not an Apollo specialist, just starting to use it.
Just in case, these thoughts may help you. If they don't, well, I'm sorry.
In main.js: Apollo documentation provides a slightly different set up when using Apollo Boost (https://www.apollographql.com/docs/link/links/state/#with-apollo-boost). Just in case, this is how I have set up my implementation so far.
import VueApollo from 'vue-apollo'
import ApolloClient from 'apollo-boost';
import { InMemoryCache } from 'apollo-cache-inmemory';
const cache = new InMemoryCache();
Vue.use(VueApollo)
const apolloClient = new ApolloClient({
//...whatever you may already have,
clientState: {
// "defaults" is your initial state - if empty, I think it might error out when your app launches but is not hydrated yet.
defaults: {
todoItems: [],
}
cache,
typeDefs: {...yourTypeDefs},
resolvers: {...yourResolvers},
},
});
const apolloProvider = new VueApollo({
defaultClient: apolloClient,
});
In your typeDefs: I can not see a Query Type for your todoItems:
type Query {
todoItemsQuery: [Item]
}
In your component: my own implementation was not working until I added an update method to the apollo request:
apollo: {
todoItems: {
query: todoItemsQuery,
update: data => data.todoItems
}
},

Can't access req from context

I'm using Koa.js with Apollo Server's apollo-server-koa.
I've debug the { req } and the value is undefined.
I've followed the documentation, but still got no clue.
Even if I access the req.headers.authorization and put this on HTTP Header of graphql gui:
{
"authorization": "bla"
}
the value is still undefined.
app.ts:
import cors from "#koa/cors";
import Koa from "koa";
import config from "./config/environtment";
import server from "./server";
const PORT: number = config.port;
async function bootstrap() {
try {
const app: Koa = new Koa();
server.applyMiddleware({ app });
app
.use(cors())
.listen(PORT, () =>
console.log(
`Server running on http://localhost:${PORT}${server.graphqlPath}`,
),
);
} catch (error) {
console.error(error);
}
}
bootstrap();
server.ts:
import { ApolloServer } from "apollo-server-koa";
import typeDefs from "./graphql/schema";
import resolvers from "./graphql/resolvers";
import context from "./graphql/context";
export default new ApolloServer({
typeDefs,
resolvers,
context,
});
context.ts
export default ({ req }) => {
console.log(req) // return undefined.
return {
test: "test",
};
};
The docs are specific to apollo-server, which uses apollo-server-express under the hood. I believe for apollo-server-koa, the options are passed in an object with a ctx field that holds the Koa Context. So the following should work:
export default ({ ctx }) => {
console.log(ctx.request)
console.log(ctx.response)
return {};
};

Apollo GraphQL - Import .graphql schema as typeDefs

With graphql-yoga you can simply import your schema by doing the following: typeDefs: './src/schema.graphql'. Is there a similar way of doing so with apollo-server-express?
If there isn't, how does one import the typeDefs from an external .graphql file?
I found a way of doing this by using graphql-import which does exactly what I need. See sample code below:
import { ApolloServer } from 'apollo-server-express'
import { importSchema } from 'graphql-import'
import Query from './resolvers/Query'
const typeDefs = importSchema('./src/schema.graphql')
const server = new ApolloServer({
typeDefs,
resolvers: {
Query
}
})
const app = express()
server.applyMiddleware({ app })
app.listen({ port: 4000 })
**
UPDATE: graphql-import v0.7+
**
importSchema is now async and should be handled as a promise. Just wrap it in a async function and simply await it:
async function start() {
const typeDefs = await importSchema(".src/schema.graphql")
}
You can use the function makeExecutableSchema to pass in the typeDefs. Something like this:
import { makeExecutableSchema } from 'graphql-tools';
import mySchema from './src/schema.graphql';
const app = express();
const schema = makeExecutableSchema({
typeDefs: [mySchema],
resolvers: {
...
},
});
app.use(
'/graphql',
graphqlExpress({ schema })
);
As a more recent response, following the top of the tutorial here link one can move the schema to a new file called schema.graphql and then import "fs" and "path" and input in the file so now it looks like:
const fs = require('fs');
const path = require('path');
const server = new ApolloServer({
typeDefs: fs.readFileSync(
path.join(__dirname, 'schema.graphql'),
'utf8'
),
resolvers,
})

Resources