├── .browserslistrc ├── .gitignore ├── README.md ├── apollo-server ├── context.js ├── data-sources.js ├── directives.js ├── resolvers.js ├── schema.graphql ├── server.js ├── type-defs.js └── utils │ └── db.js ├── apollo.config.js ├── babel.config.js ├── live └── db.json ├── package.json ├── vue.config.js └── yarn.lock /.browserslistrc: -------------------------------------------------------------------------------- 1 | > 1% 2 | last 2 versions 3 | not dead 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | 6 | # local env files 7 | .env.local 8 | .env.*.local 9 | 10 | # Log files 11 | npm-debug.log* 12 | yarn-debug.log* 13 | yarn-error.log* 14 | pnpm-debug.log* 15 | 16 | # Editor directories and files 17 | .idea 18 | .vscode 19 | *.suo 20 | *.ntvs* 21 | *.njsproj 22 | *.sln 23 | *.sw? 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vuemastery-graphql-server 2 | 3 | ## Project setup 4 | ``` 5 | yarn install 6 | ``` 7 | 8 | ### Compiles and hot-reloads for development 9 | ``` 10 | yarn serve 11 | ``` 12 | 13 | ### Compiles and minifies for production 14 | ``` 15 | yarn build 16 | ``` 17 | 18 | ### Customize configuration 19 | See [Configuration Reference](https://cli.vuejs.org/config/). 20 | -------------------------------------------------------------------------------- /apollo-server/context.js: -------------------------------------------------------------------------------- 1 | import { db } from './utils/db'; 2 | 3 | // eslint-disable-next-line no-unused-vars 4 | export default ({ req, connection }) => { 5 | return { 6 | db, 7 | }; 8 | }; 9 | -------------------------------------------------------------------------------- /apollo-server/data-sources.js: -------------------------------------------------------------------------------- 1 | export default function() { 2 | return {}; 3 | } 4 | -------------------------------------------------------------------------------- /apollo-server/directives.js: -------------------------------------------------------------------------------- 1 | export default { 2 | // Schema directives 3 | // https://www.apollographql.com/docs/graphql-tools/schema-directives.html 4 | } 5 | -------------------------------------------------------------------------------- /apollo-server/resolvers.js: -------------------------------------------------------------------------------- 1 | import shortid from "shortid"; 2 | 3 | export default { 4 | Query: { 5 | allBooks: (_, { search }, { db }) => { 6 | const books = db.get("books").value(); 7 | if (!search) { 8 | return books; 9 | } 10 | return books.filter((book) => 11 | book.title.toLowerCase().includes(search.toLowerCase()) 12 | ); 13 | }, 14 | getBook: (root, { id }, { db }) => 15 | db 16 | .get("books") 17 | .find({ id }) 18 | .value(), 19 | }, 20 | 21 | Mutation: { 22 | addBook: (_, { input }, { pubsub, db }) => { 23 | const newBook = { 24 | id: shortid.generate(), 25 | title: input.title, 26 | description: input.description || "", 27 | rating: input.rating || null, 28 | year: input.year, 29 | author: input.author, 30 | }; 31 | db.get("books") 32 | .push(newBook) 33 | .last() 34 | .write(); 35 | 36 | pubsub.publish("books", { addBook: newBook }); 37 | 38 | return newBook; 39 | }, 40 | deleteBook: (_, { id }, { db }) => { 41 | db.get("books") 42 | .remove({ id }) 43 | .write(); 44 | 45 | return true; 46 | }, 47 | updateBook: (_, { input }, { db }) => { 48 | const { id } = input; 49 | let bookToUpdate = db 50 | .get("books") 51 | .find({ id }) 52 | .value(); 53 | db.get("books") 54 | .find({ id }) 55 | .assign({ 56 | id, 57 | title: input.title || bookToUpdate.title, 58 | description: input.description || bookToUpdate.description, 59 | author: input.author || bookToUpdate.author, 60 | year: input.year || bookToUpdate.year, 61 | rating: input.rating || bookToUpdate.rating, 62 | }) 63 | .write(); 64 | return bookToUpdate; 65 | }, 66 | }, 67 | 68 | Subscription: { 69 | bookSub: { 70 | resolve: (payload) => { 71 | return payload.addBook; 72 | }, 73 | subscribe: (parent, args, { pubsub }) => pubsub.asyncIterator("books"), 74 | }, 75 | }, 76 | }; 77 | -------------------------------------------------------------------------------- /apollo-server/schema.graphql: -------------------------------------------------------------------------------- 1 | type Book { 2 | id: ID! 3 | title: String! 4 | description: String 5 | rating: Float 6 | author: String 7 | year: Int 8 | } 9 | 10 | input BookInput { 11 | title: String! 12 | description: String 13 | rating: Float 14 | author: String! 15 | year: Int! 16 | } 17 | 18 | input UpdateBookInput { 19 | id: ID! 20 | title: String 21 | description: String 22 | rating: Float 23 | author: String 24 | year: Int 25 | } 26 | 27 | type Query { 28 | allBooks(search: String): [Book] 29 | getBook(id: ID!): Book! 30 | } 31 | 32 | type Mutation { 33 | addBook(input: BookInput!): Book! 34 | deleteBook(id: ID!): Boolean 35 | updateBook(input: UpdateBookInput!): Book! 36 | } 37 | 38 | type Subscription { 39 | bookSub: Book! 40 | } 41 | -------------------------------------------------------------------------------- /apollo-server/server.js: -------------------------------------------------------------------------------- 1 | import path from "path"; 2 | import express from "express"; 3 | 4 | export default (app) => { 5 | app.use("/files", express.static(path.resolve(__dirname, "../live/uploads"))); 6 | }; 7 | -------------------------------------------------------------------------------- /apollo-server/type-defs.js: -------------------------------------------------------------------------------- 1 | import fs from 'fs' 2 | import path from 'path' 3 | 4 | export default fs.readFileSync(path.resolve(__dirname, './schema.graphql'), { encoding: 'utf8' }) 5 | -------------------------------------------------------------------------------- /apollo-server/utils/db.js: -------------------------------------------------------------------------------- 1 | import Lowdb from 'lowdb'; 2 | import FileSync from 'lowdb/adapters/FileSync'; 3 | import mkdirp from 'mkdirp'; 4 | import { resolve } from 'path'; 5 | 6 | mkdirp(resolve(__dirname, '../../live')); 7 | 8 | export const db = new Lowdb( 9 | new FileSync(resolve(__dirname, '../../live/db.json')), 10 | ); 11 | -------------------------------------------------------------------------------- /apollo.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | 3 | // Load .env files 4 | const { loadEnv } = require('vue-cli-plugin-apollo/utils/load-env') 5 | const env = loadEnv([ 6 | path.resolve(__dirname, '.env'), 7 | path.resolve(__dirname, '.env.local') 8 | ]) 9 | 10 | module.exports = { 11 | client: { 12 | service: env.VUE_APP_APOLLO_ENGINE_SERVICE, 13 | includes: ['src/**/*.{js,jsx,ts,tsx,vue,gql}'] 14 | }, 15 | service: { 16 | name: env.VUE_APP_APOLLO_ENGINE_SERVICE, 17 | localSchemaFile: path.resolve(__dirname, './node_modules/.temp/graphql/schema.json') 18 | }, 19 | engine: { 20 | endpoint: process.env.APOLLO_ENGINE_API_ENDPOINT, 21 | apiKey: env.VUE_APP_APOLLO_ENGINE_KEY 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ["@vue/cli-plugin-babel/preset"], 3 | }; 4 | -------------------------------------------------------------------------------- /live/db.json: -------------------------------------------------------------------------------- 1 | { 2 | "books": [ 3 | { 4 | "id": "n12clfp3K", 5 | "title": "The Guardians", 6 | "description": "In the small Florida town of Seabrook, a young lawyer named Keith Russo was shot dead at his desk as he worked late one night. The killer left no clues. There were no witnesses, no one with a motive. But the police soon came to suspect Quincy Miller, a young black man who was once a client of Russo’s...", 7 | "rating": 4.5, 8 | "author": "John Grisham", 9 | "year": 1970 10 | }, 11 | { 12 | "id": "TaFvKQmgQ", 13 | "title": "The Girl on the Train", 14 | "description": "Rachel catches the same commuter train every morning. She knows it will wait at the same signal each time, overlooking a row of back gardens. She’s even started to feel like she knows the people who live in one of the houses. ‘Jess and Jason’, she calls them. Their life – as she sees it – is perfect. If only Rachel could be that happy...", 15 | "rating": 4.2, 16 | "author": "John Grisham", 17 | "year": 2016 18 | }, 19 | { 20 | "id": "3y-67bb6Z", 21 | "title": "Fahrenheit 451", 22 | "description": "The terrifyingly prophetic novel of a post-literate future.", 23 | "rating": 4.6, 24 | "author": "Ray Bradbury", 25 | "year": 1953 26 | }, 27 | { 28 | "id": "Rw3sPphui", 29 | "title": "To Kill a Mockingbird", 30 | "description": "The perennially beloved and treacly account of growing up in a small Southern town during the Depression....To read the novel is, for most, an exercise in wish-fulfillment and self-congratulation, a chance to consider thorny issues of race and prejudice from a safe distance and with the comfortable certainty that the reader would never harbor the racist attitudes espoused by the lowlifes in the novel.", 31 | "rating": 4.6, 32 | "author": "Harper Lee", 33 | "year": 1960 34 | }, 35 | { 36 | "id": "b8eWGRQo6", 37 | "title": "The Shining", 38 | "description": "Jack Torrance’s new job at the Overlook Hotel is the perfect chance for a fresh start. As the off-season caretaker at the atmospheric old hotel, he’ll have plenty of time to spend reconnecting with his family and working on his writing. But as the harsh winter weather sets in, the idyllic location feels ever more remote . . . and more sinister", 39 | "rating": 4.7, 40 | "author": "Stephen King", 41 | "year": 1980 42 | }, 43 | { 44 | "id": "HVL-jHzdH", 45 | "title": "Foundation", 46 | "description": "The first novel in Isaac Asimov’s classic science-fiction masterpiece, the Foundation series", 47 | "rating": 4.5, 48 | "author": "Isaak Asimov", 49 | "year": 1942 50 | }, 51 | { 52 | "id": "eqbOaeNk-", 53 | "title": "The Catcher in the Rye", 54 | "description": "The hero-narrator of The Catcher in the Rye is an ancient child of sixteen, a native New Yorker named Holden Caulfield.Through circumstances that tend to preclude adult, secondhand description, he leaves his prep school in Pennsylvania and goes underground in New York City for three days.", 55 | "rating": 4.6, 56 | "author": "J. D. Salinger", 57 | "year": 1951 58 | } 59 | ] 60 | } 61 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vuemastery-graphql-server", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "apollo": "vue-cli-service apollo:start" 7 | }, 8 | "dependencies": { 9 | "core-js": "^3.6.5", 10 | "graphql-type-json": "^0.2.1", 11 | "lowdb": "^1.0.0", 12 | "mkdirp": "^0.5.1", 13 | "shortid": "^2.2.8", 14 | "vue-apollo": "^3.0.0-beta.11" 15 | }, 16 | "devDependencies": { 17 | "@vue/cli-plugin-babel": "~4.5.0", 18 | "@vue/cli-service": "~4.5.0", 19 | "graphql-tag": "^2.9.0", 20 | "vue-cli-plugin-apollo": "~0.22.2", 21 | "vue-template-compiler": "^2.6.11" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /vue.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | pluginOptions: { 3 | apollo: { 4 | enableMocks: false, 5 | enableEngine: false 6 | } 7 | } 8 | } 9 | --------------------------------------------------------------------------------