Building a CRUD App with Vue and GraphQL

Building a CRUD App with Vue and GraphQL
In this tutorial, we’ll learn to build a CRUD app with Vue and GraphQL.


You will need several prerequisites for this tutorial:

  • Node.js and NPM installed on your development machine. You can go to the official website for downloading both of them or use NVM to easily install Node.js in your system.
  • Knowledge of JavaScript and familiarity with Vue.
  • You have followed the previous tutorial for creating the GraphQL server.

If you have these prerequisites, let’s get started.

Enabling CORS in the Server

Since we are sending requests locally between two different ports which are considered as two separate domains we’ll need to enable Cross-Origin Resource Sharing (CORS) in the server.

First, clone the code from the GitHub repository:

git clone

Next, navigate to your project and install the dependencies and the cors module:

cd node-express-graphql-api
npm install
npm install cors --save

After that, open the index.js file and import the cors module:

const cors = require('cors');

Then, add the cors middleware to the Express app:

    const  app  =  express();

Finally, start the server:

node index.js

Your GraphQL server will be available from the [http://localhost:4000/](http://localhost:4000/) address.

Installing Vue CLI 3

We need to install Vue CLI to quickly generate Vue projects and work with them. Open a new terminal and run the following command:

npm install -g @vue/cli

As of the time of this writing, @vue/cli v3.8.2 will be installed on your system.

Creating a Vue Project

Using Vue CLI, let’s proceed to create a Vue project. Head back to your terminal and run the following command:

vue create vue-graphql-demo

When prompted to pick a preset, you can simply select the default one.

Wait for your project to be generated and run the following commands to start the development server:

cd vue-graphql-demo
npm run serve

Your app will be running on the [http://localhost:8080/](http://localhost:8080/) address.

Building a CRUD App with Vue and GraphQL

Installing the Apollo Client

Apollo is a set of utilities to help you use GraphQL in your apps. It’s well known for its client and its server. Apollo is developed and maintained by the Meteor Development Group.

Open a new terminal, navigate to your project’s folder and run the following command to install the Apollo client in your Vue project:

npm install --save vue-apollo graphql apollo-boost

Apollo Boost is a zero-config way to start using Apollo Client. It includes some common defaults, such as the recommended InMemoryCache and HttpLink, which come configured for you with the recommended settings. It’s suitable for starting to develop fast.

In the src/main.js file, add the following code to create an instance of the Apollo client and connect it to our GraphQL server running at [http://localhost:4000/graphql](http://localhost:4000/graphql):

    import ApolloClient from "apollo-boost"
    import VueApollo from "vue-apollo"
    const apolloClient = new ApolloClient({
      uri: "http://localhost:4000/graphql"
    const apolloProvider = new VueApollo({
      defaultClient: apolloClient,

We import Apollo Client from the apollo-boost package and VueApollo from the vue-apollo package. Next, we create an instance of the Apollo Client and we pass in the URL of our GraphQL endpoint.

Then, we use the VueApollo plugin to integrate Apollo with our Vue application.

Finally, we create the Apollo Provider which holds the instance of the Apollo Client that will be available to all Vue components.

All we have to do now is adding the Apollo Provider to the Vue instance using the apolloProvider option:

    new Vue({
      render: h => h(App),

That’s it. We are now ready to use the Apollo client in our Vue app.

See the docs for more information.

Consuming the GraphQL API

After adding vue-apollo to our app, all our components can use Apollo through the apollo option.

First, open the src/App.vue component and add the data() function to the exported object with the following variables:

    export default {
      name: 'app',
        return {
          id: null,
          firstName: '',
          lastName: '',
          email: ''}

We define four component variables, which are id, firstName, lastName, and email. These will be bound to the HTML form for creating a new contact.

Sending a GraphQL Query for Reading Data

Next, import gql from the graphql-tag package and add the apollo object to the component with the query that we’ll be making to read the contacts from the GraphQL API:

    import gql from 'graphql-tag'
    export default {
      name: 'app',
      /* [...] */
      apollo: {
        contacts: gql`query {
          contacts {

gql is a JavaScript template literal tag that parses GraphQL query strings into the standard GraphQL AST. Find more information from the official repository.

In the apollo object, we added a contacts attribute that will hold the results of the contacts query. Later, we’ll use it to display the contacts in the template.

Sending Mutation Queries for Creating, Updating and Deleting Data

Next, add the createContact(), updateContact() and deleteContact() methods as follows:

      methods: {
        createContact(firstName, lastName, email){
          console.log(`Create contact: ${email}`)
              mutation: gql`mutation createContact($firstName: String!, $lastName: String!, $email: String!){
                createContact(firstName: $firstName, lastName: $lastName, email: $email) {
                firstName: firstName,
                lastName: lastName,
                email: email
        updateContact(id, firstName, lastName, email){
          console.log(`Update contact: # ${id}`)
              mutation: gql`mutation updateContact($id: ID!, $firstName: String!, $lastName: String!, $email: String!){
                updateContact(id: $id, firstName: $firstName, lastName: $lastName, email: $email)
                id: id,
                firstName: firstName,
                lastName: lastName,
                email: email
          console.log(`Delete contact: # ${id}`)
              mutation: gql`mutation deleteContact($id: ID!){
                deleteContact(id: $id)
                id: id,

In the three methods, we use the this.$apollo.mutate() method to send mutations to the GraphQL server and we call the location.reload() method to reload the page.

See the docs for more information about sending mutations.

Next, add the selectContact() and clearForm() methods in the methods object:

          this.firstName = contact.firstName;
          this.lastName = contact.lastName;
 = null;
          this.firstName = '';
          this.lastName = '';
 = '';

These two methods will be used to select a contact from the table into the form and clear the form.

Adding the Template

Let’s now add a table and form for displaying, creating, updating and deleting contacts. Let’s start with the HTML table:

      <div id="app">
      <table border='1' width='100%' style='border-collapse: collapse;'>
         <th>First Name</th>
         <th>Last Name</th>
       <tr v-for='contact in contacts'>
         <td>{{ contact.firstName }}</td>
         <td>{{ contact.lastName }}</td>
         <td>{{ }}</td>
          <input type="button" @click="selectContact(contact)" value="Select">
          <input type="button" @click="deleteContact(" value="Delete">

We use the v-for directive to iterate over the contacts property of the Apollo object which holds the contacts fetched from the server. We also add two buttons for selecting and deleting the corresponding contact.

Next, let’s add the form below the table:

          <label>First Name</label>
          <input type="text" name="firstName" v-model="firstName">
          <label>Last Name</label>
          <input type="text" name="lastName" v-model="lastName">
          <input type="email" name="email" v-model="email">
          <input v-if="!id" type="button" @click="createContact(firstName, lastName, email)" value="Add">
          <input v-if="id" type="button" @click="updateContact(id, firstName, lastName, email)" value="Update">
          <input type="button" @click="clearForm()" value="Clear">

We created a form with three inputs that are bound to the firstName, lastName and email variables declared in the component. We also added three buttons for creating a new contact, updating a selected contact and clearing the form.

This is a screenshot of the UI after adding a bunch of data:

Building a CRUD App with Vue and GraphQL

After selecting a contact using the Select button, it will be loaded in the form and the Update button will appear instead of the Add button:

Building a CRUD App with Vue and GraphQL


In this tutorial, we’ve learned how to use the Apollo client to consume a GraphQL API. We’ve seen how to install Apollo, how to integrate it with Vue.js and send queries and mutations to read, create, update and delete contacts from the database.

You can find the source code of this demo for this GitHub repository.

Thanks for reading

If you liked this post, share it with all of your programming buddies!

Follow us on Facebook | Twitter

Further reading

Vue JS 2 - The Complete Guide (incl. Vue Router & Vuex)

Nuxt.js - Vue.js on Steroids

The Modern GraphQL Bootcamp (Advanced Node.js)

NodeJS - The Complete Guide (incl. MVC, REST APIs, GraphQL)

Build a Basic CRUD App with Node and React

Laravel 5.8 Ajax CRUD tutorial using Datatable JS

Build a CRUD Operation using PHP & MongoBD

Node, Express, React.js, Graphql and MongoDB CRUD Web Application

Angular 8 + Spring Boot 2.2: Build a CRUD App Today!

MEAN Stack Angular 8 CRUD Web Application

How to create a simple CRUD App using GraphQL and Node.js


Learn Startup - Build a successful business and change the world

Here are 380 Ivy League courses you can take online right now for free

Most Popular JavaScript Frameworks 2019 - I'm Programmer

Building a Video Blog with Gatsby and Markdown (MDX)

How to check if Checkbox is Checked or not using Plain JavaScript

10 Node Frameworks to Use in 2019