mirror of
https://github.com/sergeyyarkov/todo-app.git
synced 2026-10-11 10:29:14 +03:00
graphql server
This commit is contained in:
parent
6f6cc2bdc9
commit
2f07fcce8f
3
server/.gitignore
vendored
3
server/.gitignore
vendored
@ -1 +1,2 @@
|
|||||||
/node_modules
|
/node_modules
|
||||||
|
/config
|
||||||
@ -1,14 +0,0 @@
|
|||||||
const books = [
|
|
||||||
{
|
|
||||||
title: 'Harry Potter and the Chamber of Secrets',
|
|
||||||
author: 'J.K. Rowling',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Jurassic Park',
|
|
||||||
author: 'Michael Crichton',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
books,
|
|
||||||
}
|
|
||||||
@ -1,11 +0,0 @@
|
|||||||
const { books } = require('../data/index')
|
|
||||||
|
|
||||||
class Book {
|
|
||||||
static all() {
|
|
||||||
return books
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
Book,
|
|
||||||
}
|
|
||||||
10
server/models/Category.js
Normal file
10
server/models/Category.js
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
const mongoose = require('mongoose')
|
||||||
|
|
||||||
|
const categorySchema = new mongoose.Schema({
|
||||||
|
title: String,
|
||||||
|
description: String,
|
||||||
|
createdAt: String,
|
||||||
|
updatedAt: String,
|
||||||
|
})
|
||||||
|
|
||||||
|
module.exports = mongoose.model('Category', categorySchema)
|
||||||
11
server/models/Todo.js
Normal file
11
server/models/Todo.js
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
const mongoose = require('mongoose')
|
||||||
|
|
||||||
|
const todoSchema = mongoose.Schema({
|
||||||
|
title: String,
|
||||||
|
createdAt: String,
|
||||||
|
updatedAt: String,
|
||||||
|
status: String,
|
||||||
|
categoryId: String,
|
||||||
|
})
|
||||||
|
|
||||||
|
module.exports = mongoose.model('Todo', todoSchema)
|
||||||
@ -1,5 +1,7 @@
|
|||||||
const { Book } = require('./Book')
|
const Todo = require('./Todo')
|
||||||
|
const Category = require('./Category')
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
Book,
|
Todo,
|
||||||
|
Category,
|
||||||
}
|
}
|
||||||
|
|||||||
19
server/package-lock.json
generated
19
server/package-lock.json
generated
@ -869,6 +869,14 @@
|
|||||||
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
|
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"config": {
|
||||||
|
"version": "3.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/config/-/config-3.3.1.tgz",
|
||||||
|
"integrity": "sha512-+2/KaaaAzdwUBE3jgZON11L1ggLLhpf2FsGrfqYFHZW22ySGv/HqYIXrBwKKvn+XZh1UBUjHwAcrfsSkSygT+Q==",
|
||||||
|
"requires": {
|
||||||
|
"json5": "^2.1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"configstore": {
|
"configstore": {
|
||||||
"version": "5.0.1",
|
"version": "5.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz",
|
||||||
@ -1557,6 +1565,14 @@
|
|||||||
"integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=",
|
"integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"json5": {
|
||||||
|
"version": "2.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz",
|
||||||
|
"integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==",
|
||||||
|
"requires": {
|
||||||
|
"minimist": "^1.2.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
"kareem": {
|
"kareem": {
|
||||||
"version": "2.3.1",
|
"version": "2.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/kareem/-/kareem-2.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/kareem/-/kareem-2.3.1.tgz",
|
||||||
@ -1683,8 +1699,7 @@
|
|||||||
"minimist": {
|
"minimist": {
|
||||||
"version": "1.2.5",
|
"version": "1.2.5",
|
||||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
|
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
|
||||||
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
|
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"mongodb": {
|
"mongodb": {
|
||||||
"version": "3.5.8",
|
"version": "3.5.8",
|
||||||
|
|||||||
@ -14,6 +14,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"apollo-server": "^2.14.2",
|
"apollo-server": "^2.14.2",
|
||||||
|
"config": "^3.3.1",
|
||||||
"graphql": "^15.0.0",
|
"graphql": "^15.0.0",
|
||||||
"mongoose": "^5.9.18"
|
"mongoose": "^5.9.18"
|
||||||
}
|
}
|
||||||
|
|||||||
16
server/readme.md
Normal file
16
server/readme.md
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
# 🚀 GraphQL API
|
||||||
|
|
||||||
|
### Start:
|
||||||
|
```bash
|
||||||
|
npm install
|
||||||
|
npm start
|
||||||
|
```
|
||||||
|
|
||||||
|
### Enviroment variables:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"db": "mongodb://localhost:27017", // db url
|
||||||
|
"port": 3001 // server port
|
||||||
|
}
|
||||||
|
```
|
||||||
@ -1,11 +0,0 @@
|
|||||||
const { Book } = require('../models')
|
|
||||||
|
|
||||||
const bookResolvers = {
|
|
||||||
Query: {
|
|
||||||
books: () => Book.all(),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
bookResolvers,
|
|
||||||
}
|
|
||||||
31
server/resolvers/categoryResolvers.js
Normal file
31
server/resolvers/categoryResolvers.js
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
const { Category, Todo } = require('../models')
|
||||||
|
|
||||||
|
const categoryResolvers = {
|
||||||
|
Query: {
|
||||||
|
categories: () => Category.find({}),
|
||||||
|
category: (_, { id }) => Category.findById(id),
|
||||||
|
},
|
||||||
|
Mutation: {
|
||||||
|
createCategory: (_, { title, description }) => {
|
||||||
|
const category = new Category({
|
||||||
|
title,
|
||||||
|
description,
|
||||||
|
createdAt: new Date().toISOString(),
|
||||||
|
updatedAt: new Date().toISOString(),
|
||||||
|
})
|
||||||
|
return category.save()
|
||||||
|
},
|
||||||
|
deleteCategory: async (_, { id }) => {
|
||||||
|
const deletedCategory = await Category.findByIdAndRemove(id)
|
||||||
|
return deletedCategory
|
||||||
|
},
|
||||||
|
updateCategory: (_, { id, title, description }) => Category.findByIdAndUpdate(id, { $set: { title, description, updatedAt: new Date().toISOString() } }, { new: true })
|
||||||
|
},
|
||||||
|
Category: {
|
||||||
|
todos: ({ id }) => Todo.find({ categoryId: id }),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
categoryResolvers,
|
||||||
|
}
|
||||||
@ -1,6 +1,7 @@
|
|||||||
const { bookResolvers } = require('./bookResolvers')
|
const { todoResolvers } = require('./todoResolvers')
|
||||||
|
const { categoryResolvers } = require('./categoryResolvers')
|
||||||
|
|
||||||
const resolvers = [bookResolvers]
|
const resolvers = [todoResolvers, categoryResolvers]
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
resolvers,
|
resolvers,
|
||||||
|
|||||||
32
server/resolvers/todoResolvers.js
Normal file
32
server/resolvers/todoResolvers.js
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
const { Todo, Category } = require('../models')
|
||||||
|
|
||||||
|
const todoResolvers = {
|
||||||
|
Query: {
|
||||||
|
todos: () => Todo.find({}),
|
||||||
|
todo: (_, { id }) => Todo.findById(id),
|
||||||
|
},
|
||||||
|
Mutation: {
|
||||||
|
createTodo: (_, { title, categoryId }) => {
|
||||||
|
const todo = new Todo({
|
||||||
|
title,
|
||||||
|
createdAt: new Date().toISOString(),
|
||||||
|
updatedAt: new Date().toISOString(),
|
||||||
|
status: 'open',
|
||||||
|
categoryId,
|
||||||
|
})
|
||||||
|
return todo.save()
|
||||||
|
},
|
||||||
|
deleteTodo: async (_, { id }) => {
|
||||||
|
const deletedTodo = await Todo.findByIdAndRemove(id)
|
||||||
|
return deletedTodo
|
||||||
|
},
|
||||||
|
updateTodo: (_, { id, title, status, categoryId }) => Todo.findByIdAndUpdate(id, { $set: { title, updatedAt: new Date().toISOString(), status, categoryId } }, { new: true }),
|
||||||
|
},
|
||||||
|
Todo: {
|
||||||
|
category: ({ categoryId }) => Category.findById(categoryId),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
todoResolvers,
|
||||||
|
}
|
||||||
@ -2,14 +2,27 @@ const { ApolloServer } = require('apollo-server')
|
|||||||
const { typeDefs } = require('./typeDefs')
|
const { typeDefs } = require('./typeDefs')
|
||||||
const { resolvers } = require('./resolvers')
|
const { resolvers } = require('./resolvers')
|
||||||
|
|
||||||
const PORT = 3001
|
const mongoose = require('mongoose')
|
||||||
|
const config = require('config')
|
||||||
|
const port = config.get('port')
|
||||||
|
|
||||||
const startServer = async () => {
|
const startServer = async () => {
|
||||||
const server = new ApolloServer({ typeDefs, resolvers })
|
try {
|
||||||
|
const server = new ApolloServer({ typeDefs, resolvers })
|
||||||
|
await mongoose.connect(config.get('db'), {
|
||||||
|
useNewUrlParser: true,
|
||||||
|
useUnifiedTopology: true,
|
||||||
|
useFindAndModify: false,
|
||||||
|
})
|
||||||
|
|
||||||
server.listen(PORT, () => {
|
console.log('✔️ Database connected!')
|
||||||
console.log(`Apollo server is running on port: ${PORT}`)
|
|
||||||
})
|
server.listen({ port }).then(() => {
|
||||||
|
console.log(`Apollo server is running on port: ${port}!`)
|
||||||
|
})
|
||||||
|
} catch (err) {
|
||||||
|
console.log(`❌ Something went wrong: \n ${err}`)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
startServer()
|
startServer()
|
||||||
|
|||||||
@ -1,7 +1,10 @@
|
|||||||
const { query } = require('./query')
|
const { query } = require('./query')
|
||||||
const { bookType } = require('./types/bookType')
|
const { mutation } = require('./mutation')
|
||||||
|
|
||||||
const typeDefs = [query, bookType]
|
const { todoType } = require('./types/todoType')
|
||||||
|
const { categoryType } = require('./types/categoryType')
|
||||||
|
|
||||||
|
const typeDefs = [query, mutation, todoType, categoryType]
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
typeDefs,
|
typeDefs,
|
||||||
|
|||||||
19
server/typeDefs/mutation.js
Normal file
19
server/typeDefs/mutation.js
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
const { gql } = require('apollo-server')
|
||||||
|
|
||||||
|
const mutation = gql`
|
||||||
|
type Mutation {
|
||||||
|
# Todo mutations
|
||||||
|
createTodo(title: String!, categoryId: String!): Todo
|
||||||
|
deleteTodo(id: ID!): Todo
|
||||||
|
updateTodo(id: ID! title: String! status: String! categoryId: String!): Todo
|
||||||
|
|
||||||
|
# Category mutations
|
||||||
|
createCategory(title: String!, description: String!): Category
|
||||||
|
deleteCategory(id: ID!): Category
|
||||||
|
updateCategory(id: ID! title: String! description: String!): Category
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
mutation
|
||||||
|
}
|
||||||
@ -2,7 +2,10 @@ const { gql } = require('apollo-server')
|
|||||||
|
|
||||||
const query = gql`
|
const query = gql`
|
||||||
type Query {
|
type Query {
|
||||||
books: [Book]
|
todos: [Todo]
|
||||||
|
todo(id: ID!): Todo
|
||||||
|
categories: [Category]
|
||||||
|
category(id: ID!): Category
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
|
|||||||
@ -1,12 +0,0 @@
|
|||||||
const { gql } = require('apollo-server')
|
|
||||||
|
|
||||||
const bookType = gql`
|
|
||||||
type Book {
|
|
||||||
title: String
|
|
||||||
author: String
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
bookType,
|
|
||||||
}
|
|
||||||
16
server/typeDefs/types/categoryType.js
Normal file
16
server/typeDefs/types/categoryType.js
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
const { gql } = require('apollo-server')
|
||||||
|
|
||||||
|
const categoryType = gql`
|
||||||
|
type Category {
|
||||||
|
id: ID
|
||||||
|
title: String
|
||||||
|
description: String
|
||||||
|
createdAt: String
|
||||||
|
updatedAt: String
|
||||||
|
todos: [Todo]
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
categoryType,
|
||||||
|
}
|
||||||
@ -1,5 +1,7 @@
|
|||||||
const { bookType } = require('./bookType')
|
const { todoType } = require('./todoType')
|
||||||
|
const { categoryType } = require('./categoryType')
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
bookType,
|
todoType,
|
||||||
|
categoryType,
|
||||||
}
|
}
|
||||||
|
|||||||
17
server/typeDefs/types/todoType.js
Normal file
17
server/typeDefs/types/todoType.js
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
const { gql } = require('apollo-server')
|
||||||
|
|
||||||
|
const todoType = gql`
|
||||||
|
type Todo {
|
||||||
|
id: ID
|
||||||
|
title: String
|
||||||
|
createdAt: String
|
||||||
|
updatedAt: String
|
||||||
|
status: String
|
||||||
|
categoryId: String
|
||||||
|
category: Category
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
todoType,
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user