I am new to Graphql, express, and Apollo.
Expected result: I am trying to consume data from JSON file data and get results in the studio.
Actual Result: Getting "null" data instead.
I am attaching my code snippets and problems below
Refer the following:
Let me show you the code:
directory structure:
MOCK_DATA.json
I am just keeping data small for testing the concept.
[{
"name": "Leanne Graham",
"username": "Bret"
},
{
"name": "Rohit Sharma",
"username": "rohituid"
}]
index.js
As per my understanding, The significance of the file is wiring up the express middle wire with the Apollo server. Tried to make this file in a way that it will be hardly touched.
Other than that, I have the async function was required to fix Apollo Server await server.start bug .
I am creating apollo server
const { ApolloServer } = require("apollo-server-express");
const { typeDefs } = require("./Schema/TypeDefs");
const { resolver } = require("./Schema/Resolver");
const express = require("express");
const app = express();
const PORT = 3001;
async function createApolloServer() {
//passing into apollo constructor
const server = new ApolloServer({
typeDefs,
resolver
});
//instantiatiating the apollo server
await server.start();
//this will install the apollo server on express app
server.applyMiddleware({ app });
}
createApolloServer();
//console.log(resolver);
app.listen(PORT, () => {
console.log('Server is running on : http://localhost:3001/graphql');
Schema:
TypeDefs.js
const { ApolloServer, gql } = require("apollo-server");
//below is known as tagged template literal
const typeDefs = gql`
type User {
name: String
username: String
}
#Queries -like get in REST World
type Query {
getAllUsers: [User]
}
`;
//console.log(typeDefs);
module.exports = { typeDefs };
Resolver.js
const userData = require("../MOCK_DATA.json");
//const userData = require("../FakeData.js");
// this is resolver map -> javascript object
//using arrow function
/*
below arrow function equivalent to using function like:
function getAllUsers() {
return userData;
}
*/
const resolver = {
Query: {
getAllUsers: ()=> {
return userData;
}
},
};
//console.log(userData);
module.exports = { resolver };
Related
I am using graphql, prisma & express to test simple query & mutation but when I am sending data from postman I am not getting the data sent from postman,
I am sending this mutation to graphql but inside server.js file
mutation{
createUser(user_name:"test"){
user_name
}
}
, I am getting undefined,
In REST API you can use body parser to fix this for json, Is there anything like same to deal with query & mutaion of graphql with prisma & express
const { PrismaClient } = require('#prisma/client');
const express = require('express');
const { graphqlHTTP } = require('express-graphql');
const { makeExecutableSchema } = require('#graphql-tools/schema');
const prisma = new PrismaClient();
const typeDefs = `
type User {
user_name: String
}
type Query {
allUsers: [User!]!
}
type Mutation {
createUser(user_name:String):User
}
`;
const resolvers = {
Query: {
allUsers: () => {
console.log(prisma)
return prisma.user.findMany();
}
},
Mutation:{
createUser:async(user_name)=>{
console.log(user_name)
user={
"user_name":user_name
}
const test= await prisma.user.create({ data: user })
return test
}
}
};
const schema = makeExecutableSchema({
resolvers,
typeDefs,
});
const app = express();
app.use('/graphql', graphqlHTTP({
schema,
}));
app.listen(5000);
Arguments to your GraphQl query/mutation are passed through the second argument (typically defined as args) of your resolver. Update your Mutation like this
Mutation: {
createUser: async (parent, args, context) => {
console.log(args.user_name);
user = {
user_name: args.user_name,
};
const test = await prisma.user.create({ data: user });
return test;
},
},
I was able to run your code as is after this modification.
I would recommend checking out the documentation for express-graphql or some example code to get more familiar with how the library works. This example is a good place to start how to use express, graphql and prisma. It's in typescript but works very similar to what you need.
I've managed to have a express + Apollo Backend as a serverMiddleware in Nuxtjs.
Everything works fine(auth, cache, datasources, queries, mutations) but now I'm trying to get subscriptions(websockets) running and its giving me a hard time.
I tried this example https://www.apollographql.com/docs/apollo-server/data/subscriptions/#subscriptions-with-additional-middleware but even letting the httpServer listening didn't work.
This is my API file which I require through the nuxt.config.js with '~/api/index' :
module.exports = async () => {
const app = require('express')()
const server = await require("./apollo")() // apollo-server-express w/ typeDefs and resolvers
// apply Apollo to Express
server.applyMiddleware({ app });
console.log(`π ApolloServer ready at ${server.graphqlPath}`);
const httpServer = http.createServer(app);
server.installSubscriptionHandlers(httpServer);
console.log(`π ApolloSubscriptions ready at ${server.subscriptionsPath}`);
return {
path: '/api',
handler: httpServer
}
}
Now my playground is giving me this error: "Could not connect to websocket endpoint ws://192.168.150.98:3000/api/graphql. Please check if the endpoint url is correct."
TypeDefs:
type Subscription {
postAdded: Post
}
type Post {
author: String
comment: String
}
type Query {
posts: [Post]
}
type Mutation {
addPost(author: String, comment: String): Post
}
Resolvers:
Query: {
posts(root, args, context) {
return Posts;
}
}
Mutation: {
addPost(root, args, context) {
pubsub.publish(POST_ADDED, { postAdded: args });
return Posts.add(args);
}
},
Subscription: {
postAdded: {
// Additional event labels can be passed to asyncIterator creation
subscribe: () => pubsub.asyncIterator([POST_ADDED]),
},
}
First question here, thank u in advance! :)
it can also be a little easier
1.
yarn add apollo-server-express
or
npm install apollo-server-express
create file ./server/index.js
import { ApolloServer, gql } from 'apollo-server-express'
// Construct a schema, using GraphQL schema language
const typeDefs = gql`
type Query {
hello: String
}
`
// Provide resolver functions for your schema fields
const resolvers = {
Query: {
hello: () => 'Hello world!',
},
}
const server = new ApolloServer({ typeDefs, resolvers })
export default server
add in your nuxt.config.js
import server from './server'
export default {
// ... your nuxt config stuff
// ...
hooks: {
render: {
async before({
nuxt: {
server: { app },
},
}) {
await server.applyMiddleware({ app, path: '/api' })
console.log(`π ApolloServer ready at /api`)
},
},
}
}
I found a hacky way to achieve it, import the code as a nuxt module:
import http from 'http'
export default function () {
this.nuxt.hook('render:before', async () => {
const server = require("./apollo")()
// apply Apollo to Express
server.applyMiddleware({ app: this.nuxt.renderer.app });
console.log(`π ApolloServer ready at ${server.graphqlPath}`);
const httpServer = http.createServer(this.nuxt.renderer.app);
// apply SubscriptionHandlers to httpServer
server.installSubscriptionHandlers(httpServer);
console.log(`π ApolloSubscriptions ready at ${server.subscriptionsPath}`);
// overwrite nuxt.server.listen()
this.nuxt.server.listen = (port, host) => new Promise(resolve => httpServer.listen(port || 3000, host || 'localhost', resolve))
// close this httpServer on 'close' event
this.nuxt.hook('close', () => new Promise(httpServer.close))
})
}
Tho I'm now using a probably more stable way, using nuxt programmatically!
With hapi instead of express, since express is giving me trouble compiling and not showing the loading-screen(progress of building).
Just use npx create-nuxt-app and create an app with a hapi server backend.
The code with hapi would look like this:
const consola = require('consola')
const Hapi = require('#hapi/hapi')
const HapiNuxt = require('#nuxtjs/hapi')
async function start () {
const server = require('./apollo/index')()
const app = new Hapi.Server({
host: process.env.HOST || '127.0.0.1',
port: process.env.PORT || 3000
})
await app.register({
plugin: HapiNuxt
})
app.route(await require('./routes')())
await server.applyMiddleware({
app,
path: '/graphql'
});
console.log(`π ApolloServer ready at ${server.graphqlPath}`);
await server.installSubscriptionHandlers(app.listener)
console.log(`π ApolloSubscriptions ready at ${server.subscriptionsPath}`);
await app.start()
consola.ready({
message: `Server running at: ${app.info.uri}`,
badge: true
})
}
process.on('unhandledRejection', error => consola.error(error))
start().catch(error => console.log(error))
Maybe i can help somebody
An easier way is to use the getMiddleware() method of Apollo Server Express:
Create a file under ./api/index.js:
const { ApolloServer, gql } = require('apollo-server-express')
const express = require('express')
const typeDefs = gql`
type Query {
hello: String
}
`
const resolvers = {
Query: {
hello: () => 'Hello world!',
},
}
const server = new ApolloServer({ typeDefs, resolvers })
const app = express()
app.use(express.json())
app.use(express.urlencoded({ extended: true }))
app.use(server.getMiddleware())
module.exports = app
and then register it in ./nuxt.config.js:
{
// other nuxt config ...
serverMiddleware: [{ path: '/api', handler: '~/api/index.js' }],
}
I'm trying to make an axios HTTP request call to an express route to retrieve a response from passport spotify. I am struggling on sending the response from express to my vue.js component. I am using Nuxt.js.
spotify.vue
export default {
data: function() {
return {
userInfo: null
};
},
mounted() {
this.$axios.get("/auth/spotify")
.then((response) => {
userInfo = response;
});
}
};
server/index.js
const express = require('express');
const passport = require('passport');
const SpotifyStrategy = require('passport-spotify').Strategy;
const keys = require('../config/keys');
const app = express();
async function start () {
passport.use(
new SpotifyStrategy(
{
clientID: keys.spotifyClientID,
clientSecret: keys.spotifyClientSecret,
callbackURL: '/auth/spotify/callback'
},
function(accessToken, refreshToken, expires_in, profile, done) {
console.log(profile);
}
)
);
app.get('/auth/spotify', passport.authenticate('spotify'), function(req,res) {
res.json(data);
});
app.get('/auth/spotify/callback', passport.authenticate('spotify'));
}
When accessing localhost:3000/auth/spotify the data I am looking for is logged. I am wondering why res.json() or res.send() is not passing the data to the axios promise in my component.
Any help would be appreciated, Thanks in advance!!!
How to pass Additional Header when calling mutation in React native apollo client ?
my Client is here:
import { HttpLink } from 'apollo-link-http';
import { ApolloClient } from 'apollo-client';
import { InMemoryCache } from 'apollo-cache-inmemory';
const makeApolloClient = (token) => {
// create an apollo link instance, a network interface for apollo client
const link = new HttpLink({
uri: 'http://x.x.x.x:xxxx/xxxx',
headers: {
Authorization: `Bearer ${token}`
},
});
// create an inmemory cache instance for caching graphql data
const cache = new InMemoryCache();
// instantiate apollo client with apollo link instance and cache instance
const client = new ApolloClient({
link,
cache
});
return client;
};
export default makeApolloClient;
If i need to add additional header to this same client when using query or mutation how can i do it ?
Is it possible with "apollo-link-context" ?
You haven't specified your React version however assuming you use Hooks you do it as follows. If you arenβt using hooks change the doc version for the links at the bottom of this answer using the drop down in the top left.
Where you have your query:
const GET_USER = gql`
query getUser{
node {
name
age
}
}
`;
Youβll want to run a query with the useQuery hook:
const { loading, error, data } = useQuery(GET_USER, {
context: {
headers: {
"Content-Type": "application/json"
}
}
})
Docs:
You can find the docs for each here:
- UseQuery: https://www.apollographql.com/docs/react/essentials/queries/
- Context Headers: https://www.apollographql.com/docs/link/links/http/#passing-context-per-query
This can be done by receiving the context which is set in mutation/query.
Setting Custom header in mutation
const [addTodo] = useMutation(ADD_TODO, {
refetchQueries: [{ query: GET_TODO }], //updating the list of todos list after adding
context: {
headers: {
"x-custom-component-add": "kkk-add",
"x-origin-server": "pure-react"
}
}
});
receiving context in middle ware which set in mutation/query
const httpLink = new HttpLink({ uri: "https://sxewr.sse.codesandbox.io/" });
const authMiddleware = new ApolloLink((operation, forward) => {
const customHeaders = operation.getContext().hasOwnProperty("headers") ? operation.getContext().headers : {};
console.log(customHeaders);
operation.setContext({
headers: {
...customHeaders
//we can also set the authorization header
// authorization: localStorage.getItem('jjjjjj'),
}
});
return forward(operation);
});
Finally passing the middleware in Apoolo Client
const client = new ApolloClient({
cache: new InMemoryCache(),
link: from([authMiddleware, httpLink])
});
Here is the working sample.
https://codesandbox.io/s/passing-custom-header-in-graphql-mutation-query-l332g?file=/src/index.js
Custom header look like this
I have react app that stores data via axios to a mongoose server. It worked perfect until I wanted to add an extra schema for different data. My schema models are separated so I thought to just add another one called PartyList.js.
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
// Define collection and schema for Items
var PartyList = new Schema({
name: {
type: String
},
song_id: {
type: String
},
port: {
type: Number
}
},{
collection: 'party'
});
module.exports = mongoose.model('PartyList', PartyList);
This is the code in my app.js.
const config = require('./database/DB');
const ServerPortRouter = require('./routes/ServerPortRoutes');
mongoose.connect(config.DB).then(
() => {console.log('Database is connected') },
err => { console.log('Can not connect to the database' +err)
});
app.use('/serverport', ServerPortRouter);
This is how I import it and try to run it (called ServerPortRoutes.js). After running a part of my application that uses this route I get a 500 (Internal Server Error). My server tells me ReferenceError: PartyList is not defined which is defined 3 lines above.
const ServerPort = require('../models/ServerPort');
const PartyList = require('../models/PartyList');
ServerPortRouter.route('/add-party').post(function (req, res) {
const PartyList = new PartyList(req.body);
PartyList.save()
.then(PartyList => {
res.json('Server added successfully');
})
.catch(err => {
res.status(500).send("unable to save to database");
});
});
The problem looks to be you are redefining a const . In your route change to const partyList = new PartyList(req.body); Then use partyList as your variable