[experimental] A GraphQL Query Builder using Knex.js
MIT License
[experimental] A Schema First GraphQL Query Builder for Knex.js
Creating a GraphQL service with a Relational Database is a hard thing. We should take care of:
union
or window functions.So, why not integrate Knex with GraphQL directly?
yarn add knex-gql
# Schema.gql
type User @table(name: "users") {
id: ID!
name: String!
posts: [Post!]! @hasMany(foreignKey: "user_id")
pageinatedPosts: [Post!]!
@hasMany(foreignKey: "user_id", type: PAGINATOR, limit: 7)
}
input UserInput {
name: String!
}
type Post @table(name: "posts") {
id: ID!
user_id: ID!
title: String!
user: User! @belongsTo(foreignKey: "user_id")
}
type Query {
user(
id: ID @where(operator: "=")
name: String @where(operator: "LIKE")
): User @first
}
type Mutation {
createUser(input: UserInput!): User! @insert
}
@table
defines which table is associated with that type.@hasMany
and belongsTo
define table relations. Relations are automatically batch loaded when executed, meaning that no N+1 problem happens.@where
filters rows when these arguments are passed.@first
will returns the first matching row.KnexGql
instanceimport { KnexGql } from 'knex-gql'
import Knex from 'knex'
import fs from 'fs/promises'
export async function getKnexGql() {
const typeDefs = await fs.readFile('./schema.gql', 'utf8')
const knex = Knex({
client: 'pg',
connection: 'postgres://postgres:[email protected]:11155/postgres',
})
const knexGql = new KnexGql({ knex, typeDefs })
await knexGql.prepareTableColumnsMap() // This loads column info before execution
return knexGql
}
import { gql } from 'knex-gql'
getKnexGql().then(async (knexGql) => {
await knexGql
.query(
gql`
mutation CreateUser {
createUser(input: { name: "Kay" }) {
id
name
}
}
`,
)
.then(console.log)
// Output:
// {
// data: {
// createUser: {
// id: 'f8f37213-060b-4b6d-843c-5fc498bcbc08',
// name: 'Kay'
// }
// }
// }
await knexGql
.query(
gql`
query GetUser {
user(name: "Kay") {
id
name
}
}
`,
)
.then(console.log)
// Output:
// {
// data: {
// user: {
// id: 'f8f37213-060b-4b6d-843c-5fc498bcbc08',
// name: 'Kay'
// }
// }
// }
})
// Documentation todo
name | description |
---|---|
@all | Get all matching records |
@belongsTo | Get the parent record of given type |
@first | Get the first matching record |
@hasMany | Get child records with pagination |
@insert | Insert a record into the type's table |
@paginate | Paginate matching records |
@table | Map table and type |
@where | Add where clause for current query |
For more details, please see Sample app. https://github.com/acro5piano/knex-gql-sample-app