-
Notifications
You must be signed in to change notification settings - Fork 39
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Breaking Changes from v0.2.0 to v1.0.2 #38
Comments
There are quite a few breaking changes for 1.0 you can read about in the README.md file but for the 500 probably stems from a change in how you call the datasource. Please follow the readme for a complete setup guide. Note: you do not have to upgrade, but it would be advised. |
Could it be coming from the Apollo Server configuration's dataSources specification, or the class extended from SQLDataSource? |
Yes, i would need to see the usage and instantiation though. Can you share your code? |
Sure: // db.js
// Using knex and SQLDataSource (https://github.com/cvburgess/SQLDataSource)
import knex from "knex"
import { DSBooks } from "../../api/server/books/datasource"
// export const db = knex({
export const db = new DSBooks({
// export const db = {
client: "sqlite3",
connection: { filename: "./sqlite.db" }, // at .meteor\local\build\programs\server
useNullAsDefault: true
}
)
// booksTableInit.js:
export const booksTableInit = async ({ db }) => db.schema.createTable("books", (table) => {
console.log(`In booksTableInit`)
table.increments()
table.string("title")
table.string("author")
table.string("idOfOwner")
return table
})
.then((table) => {
db("books").insert([
{ title: "Harry Potter and the Chamber of Secrets", author: "J.K. Rowling", idOfOwner: "f892jkf3" },
{ title: "Jurassic Park", author: "Michael Crichton", idOfOwner: "f83kfw" }
])
.then((insertResult) => {
console.log(`Inserted books. result: ${JSON.stringify(insertResult)}`)
// return db.select().from("books")
return db.select("*").from("books") // Chester Gan: Added "*" into the select method call
.then((books) => {
console.log(`books: ${JSON.stringify(books)}`)
return books.length > 0
})
})
return { books: table }
})
.catch(error => console.log(error))
// resolvers.js:
import { pubSub } from "../../startup/server/pubSub.js"
import { withFilter } from "apollo-server-express"
const subChannelBookAdded = "bookAdded"
export const resolvers = {
Query: {
// books: async (root, args, { dataSources, user }) => {
books: async (root, args, context) => {
// console.log(`Query context: ${JSON.stringify(context, null, 2)}`) //causes error: Converting circular structure to JSON
// if (!context.user) throw new Error("Please log in.")
// Chester Gan: After the refactoring, somehow this is not recognized as a function...
const books = await context.dataSources.dsBooks.getBooks(context.user ? { idOfOwner: context.user._id } : {}) //Meteor user available because of https://github.com/apollographql/meteor-integration
return books
}
},
Mutation: {
bookAdd: async (root, { title, author }, { dataSources, user }) => { //{ title, author } is args, { dataSources, user } is context. Called "destructuring assignment"
console.log(`In bookAdd mutation. user: ${JSON.stringify(user)}`)
if (user === undefined) throw new Error("Please log in.")
const latestBook = await dataSources.dsBooks.bookAdd({ book: { title, author, idOfOwner: user._id } })
pubSub.publish(subChannelBookAdded, { latestBook })
return latestBook
}
},
Subscription: {
latestBook: {
subscribe: withFilter(() => pubSub.asyncIterator(subChannelBookAdded),
(payload, variables, context) => {
console.log(`Subscription payload: ${JSON.stringify(payload)}`)
console.log(`Subscription variables: ${JSON.stringify(variables)}`)
console.log(`Subscription context: ${JSON.stringify(context)}`) //wait for this issue to be fixed: Datasources missing in the context when using subscriptions. https://github.com/apollographql/apollo-server/issues/1526
// return payload.latestBook.idOfOwner === variables.idOfOwner && payload.latestBook.idOfOwner === context.user._id //only update books added by current logged in user. return true (or don't use withFilter()) if you want everyone to see. user is added to context via SubscriptionServer onConnect.
return true
}
),
}
},
}
// apollo.js:
export const apolloServerInit = ({ db }) => {
import { ApolloServer } from "apollo-server-express"
import { getUser } from "meteor/apollo"
import { typeDefs } from "/imports/api/server/schema.js"
import { resolvers } from "/imports/api/server/resolvers.js"
import { DSBooks } from "/imports/api/server/books/datasource.js"
const server = new ApolloServer({
context: async ({ req, connection }) => {
if (connection) { // check connection for metadata. Needed for Subscriptions to work.
return { ...connection.context }
}
console.log(`req.headers.authorization: ${JSON.stringify(req.headers.authorization)}`)
return { user: await getUser(req.headers.authorization) } //when the client is logged in (ie has an unexpired Meteor login token in localStorage), resolvers will have a context.user property
},
typeDefs,
resolvers,
dataSources: () => ({
// dsBooks: new DSBooks({ db })
// dsBooks: new DSBooks(db)
dsBooks: db
// db
// dsBooks: DSBooks({ db })
}),
// Chester Gan: tried to add cache
// cache,
// cache: new RedisCache({ host: "redis-server", }), // Options are passed through to the Redis client
subscriptions: {
path: "/subscriptions",
onConnect: async (connectionParams, webSocket, context) => { //connectionParams has authToken that was set in WebSocketLink on client
console.log(`Subscription client connected using built-in SubscriptionServer.`)
console.log(`connectionParams: ${JSON.stringify(connectionParams)}`)
if (connectionParams.authToken) return { user: await getUser(connectionParams.authToken) } //puts user into subscription context so that it can be used with withFilter()
throw new Error("Missing auth token. Please log in.")
},
onDisconnect: async (webSocket, context) => {
console.log(`Subscription client disconnected.`)
}
}
})
import { WebApp } from "meteor/webapp"
server.applyMiddleware({ app: WebApp.connectHandlers }) //path option defaults to /graphql
WebApp.connectHandlers.use("/graphql", (req, res) => { if (req.method === "GET") res.end() }) // To prevent server-side exception "Can't set headers after they are sent" because GraphQL Playground (accessible in browser via /graphql) sets headers and WebApp also sets headers
server.installSubscriptionHandlers(WebApp.httpServer)
} I am also getting the following errors from the console:
|
Thank you, but you omitted some critical code - i would need to see the actual Datasource ( DSBooks ) to validate your issue |
Sorry for missing that out, here they are:
|
Hi Charles, I hope you are well, and Merry Christmas in advance. |
Unfortunately there are a lot of issues in the code but none of them seem to be with this library. for example you use |
Using I have reverted back to my previous codes and roll-backed to the 0.2.0 release; the app now works as intended. I can't understand how is it that there are a lot of issues? |
I have trouble refactoring the codes in the class corresponding to my database in order to adapt to the changes in v1.0.0 (particularly the removal of batching support).
Furthermore, ever since I updated my copy of the "datasource-sql" package, I get a server error with status code 500 when I initiate the app. Moving back to v0.2.0 prevents this from happening.
How do I rectify this without rolling back to v0.2.0?
The text was updated successfully, but these errors were encountered: