Image for post
Image for post
Photo by James Pond on Unsplash

Easy and readable React/GraphQL/Node Stack — Part 2

Zac Tolley
Apr 25, 2019 · 6 min read
Image for post
Image for post
yarn knex migrate:make project
exports.up = function(knex) {
return knex.schema
.createTable('project', project => {
project
.uuid('id')
.notNullable()
.primary()
project.string('title').notNullable()
})
.table('todo', todo => {
todo
.uuid('projectId')
.references('id')
.inTable('project')
})
}
exports.down = function(knex) {
return knex.schema
.table('todo', todo => {
todo.dropColumn('projectId')
})
.dropTable('project')
}
# server/src/db/seed/todo.jsconst uuid = require('uuid')
async function clear(knex) {
await knex('todo').del()
}

async function seed(knex) {
await clear(knex)
const projectId = uuid() await knex('project').insert({
id: projectId,
title: 'Project',
})

await knex('todo').insert({
projectId,
id: uuid(),
title: 'Test action one',
complete: false,
})
await knex('todo').insert({
projectId,
id: uuid(),
title: 'Test action two',
complete: false,
})
}
module.exports = { clear, seed }
yarn knex migrate:latest
yarn knex seed:run
# server/server/graphql/schema.graphqltype Project {
id: ID!
title: String!
todos: [Todo]
}
type Todo {
id: ID!
title: String!
complete: Boolean!
project: Project
}
type Query {
projects: [Project]
project(id: ID!): Project

todos: [Todo]
todo(id: ID!): Todo
}
type Mutation {
addProject(title: String!): Project!
updateProject(id: ID!, title: String!): Project
addTodo(title: String!): Todo!
updateTodo(id: ID!, title: String!, complete: Boolean!): Todo!
}
# server/src/graphql/resolvers/Todo.jsconst knex = require('../../db/knex')module.exports = {
id: obj => obj.id,
title: obj => obj.title,
complete: obj => obj.complete,
project: obj =>
knex('project')
.where({ id: obj.projectId })
.first(),
}

# server/src/graphql/index.js
const Query = require('./Query')
const Todo = require('./resolvers/Todo')
const resolvers = {
Query,
Todo,
}
module.exports = { resolvers }
Image for post
Image for post
const knex = require('../../db/knex')module.exports = {
id: obj => obj.id,
title: obj => obj.title,
todos: obj => knex('todo').where({ projectId: obj.id }),
}
Image for post
Image for post
# server/src/graphql/Mutation/addProject.jsconst uuid = require('uuid')
const knex = require('../../db/knex')
const addProject = async (_, args) => {
const id = uuid()
const project = { id, ...args }
await knex('project').insert(project)
return project
}
module.exports = addProject

# server/src/graphql/Mutation/index.js
const addProject = require('./addProject')
const Mutation = { addProject }
module.exports = Mutation# server/src/graphql/index.jsconst Mutation = require('./Mutation')
const Query = require('./Query')
const Project = require('./resolvers/Project')
const Todo = require('./resolvers/Todo')
const resolvers = {
Mutation,
Project,
Query,
Todo,
}
module.exports = { resolvers }
Image for post
Image for post
const uuid = require('uuid')
const knex = require('../../db/knex')
const addTodo = async (_, args) => {
const id = uuid()
const todo = { id, ...args }
await knex('todo').insert(todo)
return todo
}
module.exports = addTodo

Scropt

Building online services

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch

Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore

Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store