0
I’m trying to build a simple api with knex and apollo server, which is running, but the querys with where retuns null
the server
import { ApolloServer } from 'apollo-server'
import knex from './knex'
import { resolvers, typeDefs } from './schema'
import { UserSQLDataSource } from './schema/users/datasource'
const server = new ApolloServer({
typeDefs,
resolvers,
dataSources: () => {
return {
userDb: new UserSQLDataSource(knex),
}
},
uploads: false,
cors: {
origin: ['https://studio.apollographql.com'],
credentials: true,
},
})
server.listen(4003).then(({ url }) => {
console.log(`Server listening on url ${url}`)
})
the knex index
const knexFn = require('knex')
const knexfile = require('./knexfile')
const knex = knexFn(knexfile[process.env.NODE_ENV])
module.exports = knex
the knexfile
const dotenv = require('dotenv').config()
module.exports = {
development: {
client: process.env.DB_CLIENT,
connection: {
database: process.env.DB_NAME,
user: process.env.DB_USER,
password: process.env.DB_PASS,
},
pool: {
min: 2,
max: 10,
},
migrations: {
tableName: process.env.MIGRATION_NAME,
},
},
}
the datasource
import { DataSource } from 'apollo-datasource'
import { InMemoryLRUCache } from '@apollo/utils.keyvaluecache'
import DataLoader from 'dataloader'
export class SQLDatasource extends DataSource {
constructor(knex, tableName) {
super()
this.db = knex
this.tableName = tableName
this._loader = new DataLoader(async ids => this.batchLoaderCallback(ids))
}
initialize({ context, cache }) {
this.context = context
this.cache = cache || new InMemoryLRUCache()
}
async batchLoad(id) {
return this._loader.load(id)
}
async batchLoaderCallback(_ids) {
return _ids
}
}
the user datasource with a log to the query getUser
import { SQLDatasource } from '../../schema/datasources'
export class UserSQLDataSource extends SQLDatasource {
constructor(knex) {
super(knex, 'users')
}
async getUsers() {
return await this.db(this.tableName)
}
async getUser(id) {
try {
const query = this.db(this.tableName).where({ id: id })
console.log(query.toSQL())
return await query
} catch (error) {
console.error(error)
throw error
}
}
}
the log of the query
Server listening on url https://localhost:4003/
{
method: 'select',
options: {},
timeout: false,
cancelOnTimeout: false,
bindings: [ '1' ],
__knexQueryUid: 'sH05Z4l3pgdNm5mY9YPkeu6',
sql: 'select * from `users` where `id` = ?'
}
the user typedefs
import { gql } from 'apollo-server'
export const userTypeDefs = gql`
extend type Query {
user(id: ID!): User!
users: [User!]!
}
type User {
id: ID!
firstName: String!
lastName: String!
userName: String!
email: String!
password_hash: String!
token: String!
createdAt: String!
updatedAt: String!
}
`
the user resolvers
const users = async (_, { input }, { dataSources }) => {
const users = await dataSources.userDb.getUsers(input)
return users
}
const user = async (_, { id }, { dataSources }) => {
const user = await dataSources.userDb.getUser(id)
return user
}
export const userResolvers = {
Query: { user, users },
}
The query without the where, all users, returns ok, the query with where, using id as parameter, or changing to other column (firstname, email, etc) always return null.
I did some changes with the query, alter the parameters, same result. I don’t know if the current version with all the components is an issue, the package.json is this
{
"name": "mysql",
"version": "1.0.0",
"description": "",
"main": "src/index.js",
"scripts": {
"test": "echo "Error: no test specified" && exit 1",
"sucrase": "./src -d ./Dir --transforms imports",
"knex": "npx knex --cwd ./src/knex",
"knex-h": "npx knex --help",
"dev": "nodemon -e js src/index.js"
},
"author": "",
"license": "ISC",
"dependencies": {
"apollo-server": "^3.12.0",
"dataloader": "^2.2.2",
"datasource-sql": "^2.1.0",
"dotenv": "^16.3.1",
"graphql": "^16.8.0",
"knex": "^2.5.1",
"mysql2": "^3.6.0",
"path": "^0.12.7"
},
"devDependencies": {
"eslint": "^8.47.0",
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-prettier": "^5.0.0",
"nodemon": "^3.0.1",
"prettier": "^3.0.2",
"sucrase": "^3.34.0"
}
}
1 Answer
Reset to default
0
I ran into this when I first started using knex with Apollo as well.
A query such as:
const user = await dataSources.userDb.getUser(id);
returns an array of users of length 1. But your GraphQL query is looking for a single user.
Here are two simple patterns to get past this:
const [user] = await dataSources.userDb.getUser(id);
const user = await dataSources.userDb.getUser(id).first()
;
Not the answer you're looking for? Browse other questions tagged
or ask your own question.
or ask your own question.
|