diff --git a/server/.gitignore b/server/.gitignore index 30bc162..d049512 100644 --- a/server/.gitignore +++ b/server/.gitignore @@ -1 +1,2 @@ -/node_modules \ No newline at end of file +/node_modules +/config \ No newline at end of file diff --git a/server/data/index.js b/server/data/index.js deleted file mode 100644 index 4c6b4f9..0000000 --- a/server/data/index.js +++ /dev/null @@ -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, -} diff --git a/server/models/Book.js b/server/models/Book.js deleted file mode 100644 index 3ed8271..0000000 --- a/server/models/Book.js +++ /dev/null @@ -1,11 +0,0 @@ -const { books } = require('../data/index') - -class Book { - static all() { - return books - } -} - -module.exports = { - Book, -} diff --git a/server/models/Category.js b/server/models/Category.js new file mode 100644 index 0000000..a59d1c8 --- /dev/null +++ b/server/models/Category.js @@ -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) diff --git a/server/models/Todo.js b/server/models/Todo.js new file mode 100644 index 0000000..ebdf775 --- /dev/null +++ b/server/models/Todo.js @@ -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) diff --git a/server/models/index.js b/server/models/index.js index 813f210..385b5c0 100644 --- a/server/models/index.js +++ b/server/models/index.js @@ -1,5 +1,7 @@ -const { Book } = require('./Book') +const Todo = require('./Todo') +const Category = require('./Category') module.exports = { - Book, + Todo, + Category, } diff --git a/server/package-lock.json b/server/package-lock.json index 12093b0..5dbb89d 100644 --- a/server/package-lock.json +++ b/server/package-lock.json @@ -869,6 +869,14 @@ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "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": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", @@ -1557,6 +1565,14 @@ "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", "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": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.3.1.tgz", @@ -1683,8 +1699,7 @@ "minimist": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" }, "mongodb": { "version": "3.5.8", diff --git a/server/package.json b/server/package.json index 81a289b..44c735c 100644 --- a/server/package.json +++ b/server/package.json @@ -14,6 +14,7 @@ }, "dependencies": { "apollo-server": "^2.14.2", + "config": "^3.3.1", "graphql": "^15.0.0", "mongoose": "^5.9.18" } diff --git a/server/readme.md b/server/readme.md new file mode 100644 index 0000000..c0c7186 --- /dev/null +++ b/server/readme.md @@ -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 +} +``` diff --git a/server/resolvers/bookResolvers.js b/server/resolvers/bookResolvers.js deleted file mode 100644 index f18ffbc..0000000 --- a/server/resolvers/bookResolvers.js +++ /dev/null @@ -1,11 +0,0 @@ -const { Book } = require('../models') - -const bookResolvers = { - Query: { - books: () => Book.all(), - }, -} - -module.exports = { - bookResolvers, -} diff --git a/server/resolvers/categoryResolvers.js b/server/resolvers/categoryResolvers.js new file mode 100644 index 0000000..fa2a1dd --- /dev/null +++ b/server/resolvers/categoryResolvers.js @@ -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, +} diff --git a/server/resolvers/index.js b/server/resolvers/index.js index 1bce0f3..8ef1659 100644 --- a/server/resolvers/index.js +++ b/server/resolvers/index.js @@ -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 = { resolvers, diff --git a/server/resolvers/todoResolvers.js b/server/resolvers/todoResolvers.js new file mode 100644 index 0000000..fccc228 --- /dev/null +++ b/server/resolvers/todoResolvers.js @@ -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, +} diff --git a/server/server.js b/server/server.js index 0c10e19..d7e0b22 100644 --- a/server/server.js +++ b/server/server.js @@ -2,14 +2,27 @@ const { ApolloServer } = require('apollo-server') const { typeDefs } = require('./typeDefs') const { resolvers } = require('./resolvers') -const PORT = 3001 +const mongoose = require('mongoose') +const config = require('config') +const port = config.get('port') 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(`Apollo server is running on port: ${PORT}`) - }) + console.log('✔️ Database connected!') + + server.listen({ port }).then(() => { + console.log(`Apollo server is running on port: ${port}!`) + }) + } catch (err) { + console.log(`❌ Something went wrong: \n ${err}`) + } } startServer() diff --git a/server/typeDefs/index.js b/server/typeDefs/index.js index b17dc7d..0a9899a 100644 --- a/server/typeDefs/index.js +++ b/server/typeDefs/index.js @@ -1,7 +1,10 @@ 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 = { typeDefs, diff --git a/server/typeDefs/mutation.js b/server/typeDefs/mutation.js new file mode 100644 index 0000000..ec16da6 --- /dev/null +++ b/server/typeDefs/mutation.js @@ -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 +} \ No newline at end of file diff --git a/server/typeDefs/query.js b/server/typeDefs/query.js index f109763..0197367 100644 --- a/server/typeDefs/query.js +++ b/server/typeDefs/query.js @@ -2,7 +2,10 @@ const { gql } = require('apollo-server') const query = gql` type Query { - books: [Book] + todos: [Todo] + todo(id: ID!): Todo + categories: [Category] + category(id: ID!): Category } ` diff --git a/server/typeDefs/types/bookType.js b/server/typeDefs/types/bookType.js deleted file mode 100644 index 673ca1a..0000000 --- a/server/typeDefs/types/bookType.js +++ /dev/null @@ -1,12 +0,0 @@ -const { gql } = require('apollo-server') - -const bookType = gql` - type Book { - title: String - author: String - } -` - -module.exports = { - bookType, -} diff --git a/server/typeDefs/types/categoryType.js b/server/typeDefs/types/categoryType.js new file mode 100644 index 0000000..50384ec --- /dev/null +++ b/server/typeDefs/types/categoryType.js @@ -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, +} diff --git a/server/typeDefs/types/index.js b/server/typeDefs/types/index.js index dc8445b..ba5fafc 100644 --- a/server/typeDefs/types/index.js +++ b/server/typeDefs/types/index.js @@ -1,5 +1,7 @@ -const { bookType } = require('./bookType') +const { todoType } = require('./todoType') +const { categoryType } = require('./categoryType') module.exports = { - bookType, + todoType, + categoryType, } diff --git a/server/typeDefs/types/todoType.js b/server/typeDefs/types/todoType.js new file mode 100644 index 0000000..3f9535c --- /dev/null +++ b/server/typeDefs/types/todoType.js @@ -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, +}