Estou tentando construir uma api simples com knex e servidor apollo, que esta rodando, mas as queries com where retornam null
o servidor
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}`)
})
o índice knex
const knexFn = require('knex')
const knexfile = require('./knexfile')
const knex = knexFn(knexfile[process.env.NODE_ENV])
module.exports = knex
o arquivo knex
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,
},
},
}
a fonte de dados
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
}
}
a fonte de dados do usuário com um log para a consulta 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
}
}
}
log da query
Server listening on url http://localhost:4003/
{
method: 'select',
options: {},
timeout: false,
cancelOnTimeout: false,
bindings: [ '1' ],
__knexQueryUid: 'sH05Z4l3pgdNm5mY9YPkeu6',
sql: 'select * from `users` where `id` = ?'
}
as definições de tipo do usuário
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!
}
`
os resolvedores de usuários
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 },
}
A consulta sem o where, todos os usuários, retorna ok, a consulta com where, usando id como parâmetro, ou alterando para outra coluna (primeiro nome, email, etc) sempre retorna null.
Fiz algumas alterações na consulta, alterei os parâmetros, mesmo resultado. Não sei se a versão atual com todos os componentes é um problema, o package.json é este
{
"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"
}
}
Eu me deparei com isso quando comecei a usar o knex com o Apollo também.
Uma consulta como:
retorna uma matriz de usuários de comprimento 1. Mas sua consulta GraphQL está procurando por um único usuário.
Aqui estão dois padrões simples para superar isso:
const [user] = await dataSources.userDb.getUser(id);
const user = await dataSources.userDb.getUser(id).first()
;