├── .browserslistrc
├── .gitignore
├── README.md
├── apollo-server
├── context.js
├── directives.js
├── mocks.js
├── resolvers.js
├── schema.graphql
├── type-defs.js
└── utils
│ └── db.js
├── apollo.config.js
├── babel.config.js
├── live
└── db.json
├── package.json
├── postcss.config.js
├── public
├── favicon.ico
├── icons
│ ├── android-chrome-192x192.png
│ ├── android-chrome-256x256.png
│ ├── apple-touch-icon.png
│ ├── browserconfig.xml
│ ├── favicon-16x16.png
│ ├── favicon-32x32.png
│ ├── favicon.ico
│ ├── mstile-150x150.png
│ ├── safari-pinned-tab.svg
│ └── site.webmanifest
└── index.html
├── src
├── App.vue
├── assets
│ ├── logo.png
│ └── vue-graphql.png
├── components
│ └── VueHero.vue
├── main.js
└── vue-apollo.js
├── vue.config.js
└── yarn.lock
/.browserslistrc:
--------------------------------------------------------------------------------
1 | > 1%
2 | last 2 versions
3 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /dist
4 |
5 | # local env files
6 | .env.local
7 | .env.*.local
8 |
9 | # Log files
10 | npm-debug.log*
11 | yarn-debug.log*
12 | yarn-error.log*
13 |
14 | # Editor directories and files
15 | .idea
16 | .vscode
17 | *.suo
18 | *.ntvs*
19 | *.njsproj
20 | *.sln
21 | *.sw?
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Vue + GraphQL + Apollo fullstack example
2 |
3 | This is a demo application combining Apollo Server as a GraphQL API and a Vue application with Apollo Client on a frontend side. To start a GraphQL server, please run:
4 |
5 | ```bash
6 | npm run apollo
7 | # OR
8 | yarn apollo
9 | ```
10 |
11 | The server will be running on `localhost:4000/graphql` and you can find a Prisma playground on this URL as well to check the schema & test queries.
12 |
13 | To start the frontend app you should run
14 |
15 | ```bash
16 | npm run serve
17 | # OR
18 | yarn serve
19 | ```
20 |
21 | The application will be running on `localhost:8080`.
22 |
--------------------------------------------------------------------------------
/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/directives.js:
--------------------------------------------------------------------------------
1 | export default {
2 | // Schema directives
3 | // https://www.apollographql.com/docs/graphql-tools/schema-directives.html
4 | }
5 |
--------------------------------------------------------------------------------
/apollo-server/mocks.js:
--------------------------------------------------------------------------------
1 | // Enable mocking in vue.config.js with `"pluginOptions": { "enableMocks": true }`
2 | // Customize mocking: https://www.apollographql.com/docs/graphql-tools/mocking.html#Customizing-mocks
3 | export default {
4 | // Mock resolvers here
5 | }
6 |
--------------------------------------------------------------------------------
/apollo-server/resolvers.js:
--------------------------------------------------------------------------------
1 | import shortid from 'shortid';
2 |
3 | export default {
4 | Query: {
5 | allHeroes: (root, args, { db }) => db.get('heroes').value(),
6 | getHero: (root, { name }, { db }) =>
7 | db
8 | .get('heroes')
9 | .find({ name })
10 | .value(),
11 | },
12 |
13 | Mutation: {
14 | addHero: (root, { hero }, { pubsub, db }) => {
15 | const newHero = {
16 | id: shortid.generate(),
17 | name: hero.name,
18 | image: hero.image || '',
19 | twitter: hero.twitter || '',
20 | github: hero.github || '',
21 | };
22 | db.get('heroes')
23 | .push(newHero)
24 | .last()
25 | .write();
26 |
27 | pubsub.publish('heroes', { addHero: newHero });
28 |
29 | return newHero;
30 | },
31 | deleteHero: (root, { name }, { db }) => {
32 | db.get('heroes')
33 | .remove({ name })
34 | .write();
35 |
36 | return true;
37 | },
38 | },
39 |
40 | Subscription: {
41 | heroSub: {
42 | resolve: (payload, args, context, info) => {
43 | return payload.addHero;
44 | },
45 | subscribe: (parent, args, { pubsub }) => pubsub.asyncIterator('heroes'),
46 | },
47 | },
48 | };
49 |
--------------------------------------------------------------------------------
/apollo-server/schema.graphql:
--------------------------------------------------------------------------------
1 | ## Hero member
2 | type Hero {
3 | id: ID!
4 | name: String!
5 | image: String
6 | github: String
7 | twitter: String
8 | }
9 |
10 | input HeroInput {
11 | name: String!
12 | image: String
13 | github: String
14 | twitter: String
15 | }
16 |
17 | type Query {
18 | allHeroes: [Hero]
19 | getHero(name: String!): Hero!
20 | }
21 |
22 | type Mutation {
23 | addHero(hero: HeroInput!): Hero!
24 | deleteHero(name: String!): Boolean
25 | }
26 |
27 | type Subscription {
28 | heroSub: Hero!
29 | }
30 |
--------------------------------------------------------------------------------
/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 |
12 | // Seed an empty DB
13 | db.defaults({}).write();
14 |
--------------------------------------------------------------------------------
/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(
18 | __dirname,
19 | './node_modules/.temp/graphql/schema.json',
20 | ),
21 | },
22 | engine: {
23 | endpoint: process.env.APOLLO_ENGINE_API_ENDPOINT,
24 | apiKey: env.VUE_APP_APOLLO_ENGINE_KEY,
25 | },
26 | };
27 |
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/app'
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/live/db.json:
--------------------------------------------------------------------------------
1 | {
2 | "heroes": [
3 | {
4 | "id": "5ahW7OxdZ",
5 | "name": "Evan You",
6 | "image": "https://pbs.twimg.com/profile_images/1206997998900850688/cTXTQiHm_400x400.jpg",
7 | "twitter": "youyuxi",
8 | "github": "yyx990803"
9 | },
10 | {
11 | "id": "b0PCURlkf",
12 | "name": "Guillaume Chau",
13 | "image": "https://pbs.twimg.com/profile_images/1233016078902624256/Yh4cWtyk_400x400.jpg",
14 | "twitter": "Akryum",
15 | "github": "Akryum"
16 | },
17 | {
18 | "id": "bneqe0dcq",
19 | "name": "Eduardo San Martin Morote",
20 | "image": "https://pbs.twimg.com/profile_images/1263046393486356486/TEuM0IAV_400x400.jpg",
21 | "twitter": "posva",
22 | "github": "posva"
23 | },
24 | {
25 | "id": "Jq2uzIh4u",
26 | "name": "Sarah Drasner",
27 | "image": "https://pbs.twimg.com/profile_images/1225613270205091840/NyoNYuhC_400x400.jpg",
28 | "twitter": "sarah_edo",
29 | "github": "sdras"
30 | },
31 | {
32 | "id": "KWAXP1uT5",
33 | "name": "Thorsten Lünborg",
34 | "image": "https://pbs.twimg.com/profile_images/1139622278092722177/cNVjHMVb_400x400.jpg",
35 | "twitter": "Linus_Borg",
36 | "github": "LinusBorg"
37 | },
38 | {
39 | "id": "RX5Qbnf4z",
40 | "name": "Haoqun Jiang",
41 | "image": "https://pbs.twimg.com/profile_images/460836761199845376/dhdpOXCw_400x400.jpeg",
42 | "twitter": "haoqunjiang",
43 | "github": "sodatea"
44 | },
45 | {
46 | "id": "CgplNv299",
47 | "name": "Kazuya Kawaguchi",
48 | "image": "https://pbs.twimg.com/profile_images/1151694505298411520/7iI5124P_400x400.png",
49 | "twitter": "kazu_pon",
50 | "github": "kazupon"
51 | }
52 | ]
53 | }
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vue-graphql-example",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "serve": "vue-cli-service serve",
7 | "build": "vue-cli-service build",
8 | "apollo": "vue-cli-service apollo:dev --generate-schema",
9 | "apollo:schema:generate": "vue-cli-service apollo:schema:generate",
10 | "apollo:schema:publish": "vue-cli-service apollo:schema:publish",
11 | "apollo:start": "vue-cli-service apollo:start"
12 | },
13 | "dependencies": {
14 | "core-js": "^2.6.5",
15 | "graphql-type-json": "^0.2.1",
16 | "lowdb": "^1.0.0",
17 | "shortid": "^2.2.14",
18 | "vue": "^2.6.10",
19 | "vue-apollo": "^3.0.3",
20 | "vuetify": "^1.5.16"
21 | },
22 | "devDependencies": {
23 | "@vue/cli-plugin-babel": "^3.9.0",
24 | "@vue/cli-service": "^3.9.0",
25 | "graphql-tag": "^2.9.0",
26 | "node-sass": "^4.9.0",
27 | "sass-loader": "^7.1.0",
28 | "vue-cli-plugin-apollo": "^0.21.0",
29 | "vue-template-compiler": "^2.6.10"
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: {
3 | autoprefixer: {}
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NataliaTepluhina/vue-graphql-presentation/60c7aa87ca8dd36877ac99a372a689da1eecf8b5/public/favicon.ico
--------------------------------------------------------------------------------
/public/icons/android-chrome-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NataliaTepluhina/vue-graphql-presentation/60c7aa87ca8dd36877ac99a372a689da1eecf8b5/public/icons/android-chrome-192x192.png
--------------------------------------------------------------------------------
/public/icons/android-chrome-256x256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NataliaTepluhina/vue-graphql-presentation/60c7aa87ca8dd36877ac99a372a689da1eecf8b5/public/icons/android-chrome-256x256.png
--------------------------------------------------------------------------------
/public/icons/apple-touch-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NataliaTepluhina/vue-graphql-presentation/60c7aa87ca8dd36877ac99a372a689da1eecf8b5/public/icons/apple-touch-icon.png
--------------------------------------------------------------------------------
/public/icons/browserconfig.xml:
--------------------------------------------------------------------------------
1 |
2 |