π 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.graphqlcontains the Schema written with the schema definition language.resolvers.jsdeclares the Apollo resolvers.context.jsallows injecting a context object into all the resolvers (third argument).mocks.jsdefines the custom resolvers used for mocking (more info).directives.jsdefines 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:watchRun the GraphQL API server with info from
./apollo-serverand watch the files to restart itself automatically. -
vue-cli-service apollo:runRun the GraphQL API server with info from
./apollo-serveronce.
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_HTTPThe url to the graphql HTTP endpoint, default:
http://localhost:4000 -
VUE_APP_GRAPHQL_WSThe url to the graphql Websockets endpoint for subscriptions, default:
ws://localhost:4000
-
VUE_APP_GRAPHQL_PORTPort of the GraphQL API Server, default:
4000 -
VUE_APP_APOLLO_ENGINE_KEYAPI 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(),
})
