🚀 Start building a Vue app with Apollo and GraphQL in 2 minutes!
This is a vue-cli 3.x plugin to add Apollo and GraphQL in your Vue project.
- Automatically integrate vue-apollo into your Vue app
- Embed Apollo client config (upgradable and customizable)
- Websockets
- File uploads
- Client state with apollo-link-state
- Included optional Graphql Server (upgradable and customizable):
- Dead simple GraphQL API sources generated into your project (with import/export support)
- Upgradable service running apollo-server
- Websocket subscriptions support
- Optional automatic mocking
- Apollo Engine support
- GraphQL playground integrated in the CLI UI
- Configuration screen in the CLI UI
- Server-Side Rendering with @akryum/vue-cli-plugin-ssr
- Included optional example component with:
- Watched query
- Mutation
- Realtime subscription using Websockets
- Fully working image gallery with image upload
- GraphQL validation using ESLint
- Getting started
- Injected Commands
- Configuration
- Env variables
- Injected webpack-chain Rules
- Running the GraphQL server in production
- Manual code changes
vue --version
If you don't have a project created with vue-cli 3.x yet:
vue create my-new-app
Navigate to the newly created project folder and add the cli plugin:
cd my-new-app
vue add apollo
ℹ️ An example ApolloExample.vue
component alongside some GraphQL query files will be added into your sources if you chose to include the examples.
Start your app:
npm run serve
Updating vue-cli-plugin-apollo
will also update both Apollo Client and its configuration for you! 👍
Read the vue-apollo doc.
If you enabled the GraphQL API Server, start it (by default it also runs serve
):
npm run apollo
You can edit the files generated in the ./apollo-server
folder:
schema.graphql
contains the Schema written with the schema definition language.resolvers.js
declares the Apollo resolvers.context.js
allows injecting a context object into all the resolvers (third argument).mocks.js
defines the custom resolvers used for mocking (more info).directives.js
defines the custom schema directives (more info)).
The server will be automatically restarted when a change is detected.
To run the server only once, use this command:
npm run run-graphql-api
Updating vue-cli-plugin-apollo
will also update the GraphQL Server service 👍
-
vue-cli-service apollo:watch
Run the GraphQL API server with info from
./apollo-server
and watch the files to restart itself automatically. -
vue-cli-service apollo:run
Run the GraphQL API server with info from
./apollo-server
once.
The GraphQL API Server can be configured via the pluginOptions
in vue.config.js
:
module.exports = {
// Other options...
pluginOptions: {
// Apollo-related options
apollo: {
// Enable automatic mocking
enableMocks: true,
// Enable Apollo Engine
enableEngine: true,
/* Other options (with default values) */
// Base folder for the server source files
serverFolder: './apollo-server',
// Cross-Origin options
cors: '*',
// Requests timeout (ms)
timeout: 120000,
// Integrated apollo engine
integratedEngine: true,
// For enable typescript server files
// if you don't have @vue/cli-plugin-typescript
typescript: true,
// Apollo server options (will be merged with the included default options)
serverOptions: {
// ...
},
},
},
}
createApolloClient({
// URL to the HTTP API
httpEndpoint,
// Url to the Websocket API
wsEndpoint = null,
// Token used in localstorage
tokenName = 'apollo-token',
// Enable this if you use Query persisting with Apollo Engine
persisting = false,
// Is currently Server-Side Rendering or not
ssr = false,
// Only use Websocket for all requests (including queries and mutations)
websocketsOnly = false,
// Custom starting link.
// If you want to replace the default HttpLink, set `defaultHttpLink` to false
link = null,
// If true, add the default HttpLink.
// Disable it if you want to replace it with a terminating link using `link` option.
defaultHttpLink = true,
// Options for the default HttpLink
httpLinkOptions = {},
// Custom Apollo cache implementation (default is apollo-cache-inmemory)
cache = null,
// Options for the default cache
inMemoryCacheOptions = null,
// Additional Apollo client options
apollo = {},
// apollo-link-state options
clientState = null,
// Function returning Authorization header token
getAuth = defaultGetAuth,
})
You can use apollo-link-state for client-only local data with the clientState
option of createApolloClient
:
import { createApolloClient } from 'vue-cli-plugin-apollo/graphql-client'
const options = {
// ...
clientState: {
defaults: {
connected: false,
},
resolvers: {
Mutation: {
connectedSet: (root, { value }, { cache }) => {
const data = {
connected: value,
}
cache.writeData({ data })
},
},
},
},
}
const { apolloClient } = createApolloClient(options)
Then you need to use the @client
directive:
query isConnected {
connected @client
}
mutation setConnected ($value: Boolean!) {
connectedSet (value: $value) @client
}
By default, createApolloClient
will retrieve the Authorization
header value from localStorage
. You can override this behavior with the getAuth
option:
const options = {
// ...
getAuth: (tokenName) => getUserToken(),
}
const { apolloClient } = createApolloClient(options)
If you use cookies, you can return undefined
.
Example apolloserver/context.js
that validates the token and set userId
on resolvers context:
import users from './connectors/users'
// Context passed to all resolvers (third argument)
// req => Query
// connection => Subscription
// eslint-disable-next-line no-unused-vars
export default ({ req, connection }) => {
// If the websocket context was already resolved
if (connection && connection.context) return connection.context
let token
// HTTP
if (req) token = req.get('Authorization')
// Websocket
if (connection) token = connection.authorization
// User validation
let userId
if (token && users.validateToken(token)) {
userId = token.userId
}
return {
token,
userId,
}
}
You can enable automatic mocking on the GraphQL API Server. It can be customized in the ./apollo-server/mocks.js
file generated in your project.
You can add custom GraphQL directives in the ./apollo-server/directives.js
file (documentation).
import { SchemaDirectiveVisitor } from 'graphql-tools'
class PrivateDirective extends SchemaDirectiveVisitor {
// ...
}
export default {
// Now you can use '@private' in the schema
private: PrivateDirective
}
Apollo Engine is a commercial product from Apollo. It enables lots of additional features like monitoring, error reporting, caching and query persisting.
Create a key at https://engine.apollographql.com (it's free!).
If you need to add express middlewares into the GraphQL server, you can create a ./apollo-server/server.js
file:
import path from 'path'
import express from 'express'
const distPath = path.resolve(__dirname, '../../dist')
export default app => {
app.use(express.static(distPath))
}
-
VUE_APP_GRAPHQL_HTTP
The url to the graphql HTTP endpoint, default:
http://localhost:4000
-
VUE_APP_GRAPHQL_WS
The url to the graphql Websockets endpoint for subscriptions, default:
ws://localhost:4000
-
VUE_APP_GRAPHQL_PORT
Port of the GraphQL API Server, default:
4000
-
VUE_APP_APOLLO_ENGINE_KEY
API key for Apollo Engine
config.rule('gql')
cross-env NODE_ENV=production yarn run apollo:run --mode production
If you deploy on now.sh, add the following script to your package.json
:
{
"scripts": {
"start": "cross-env NODE_ENV=production yarn run apollo:run --mode production"
}
}
If your project is meant to be used as a package installed from npm, you will need to move vue-cli-plugin-apollo
from the devDependencies
field to dependencies
in your package.json
file. Then you can run the server:
const server = require('vue-cli-plugin-apollo/graphql-server')
const opts = {
host: 'localhost',
port: 4000,
graphqlPath: '/graphql',
subscriptionsPath: '/graphql',
enableMocks: false,
enableEngine: false,
cors: '*',
timeout: 1000000,
quiet: true,
paths: {
typeDefs: require.resolve('some-folder/apollo-server/type-defs.js'),
resolvers: require.resolve('some-folder/apollo-server/resolvers.js'),
context: require.resolve('some-folder/apollo-server/context.js'),
pubsub: require.resolve('some-folder/apollo-server/pubsub.js'),
server: require.resolve('some-folder/apollo-server/server.js'),
directives: require.resolve('some-folder/apollo-server/directives.js')
dataSources: require.resolve('some-folder/apollo-server/data-sources.js')
}
}
server(opts, () => {
console.log('Server is running!')
})
In case the plugin isn't able to modify the file containing the root Vue instance:
Import the provider:
import { createProvider } from './vue-apollo'
Then in the root instance, set the apolloProvider
option:
new Vue({
el: '#app',
// Add this line
apolloProvider: createProvider(),
})