Nuxt.js app with Hasura GraphQL Engine
12 June 2020
Create a Postgres database on Heroku
Go to Hasura and spin up a Heroku app with a Postgres database. It's all explained in Hasura docs: Quickstart with Heroku
Using the GUI create a table movies
and add the following fields to it:
title - text
id - uuid, primary key, unique, default: gen_random_uuid()
year - text, nullable
poster - text, nullable
plot - text, nullable
Feed it some sample data (poster
field should be a link to some jpeg) and move to the next chapter.
Create Nuxt.js app
Next, let's create Nuxt.js app (there are no preferences towards answers for the questions):
npx create-nuxt-app nuxt-movie-database
Install @nuxt/apollo and graphql-tag
npm install @nuxt/apollo graphql-tag --save
Configure Apollo client
Add basic config in nuxt.config.js
:
apollo: {
clientConfigs: {
default: {
httpEndpoint: 'https://hasura-movie-database.herokuapp.com/v1/graphql',
wsEndpoint: 'wss://hasura-movie-database.herokuapp.com/v1/graphql',
},
},
},
The ws
stands for WebSockets and will be required further on to subscribe to changes in the database.
Write some queries
Let's prepare a template in /pages/index.vue
:
<template>
<div>
<div>
<h1>
a basic movie database part deux
</h1>
<form>
<input
v-model="lookupMovie"
type="text"
placeholder="Enter movie title"
aria-label="Movie title"
required
/>
<button type="submit" @click.prevent="submit" @keydown="submit">
Submit
</button>
</form>
<div>
<div v-for="movie in movies" :key="movie.id">
<div>
<div>
<img :src="movie.poster" alt="Movie poster" />
</div>
<div>
<div>{{ movie.title }} ({{ movie.year }})</div>
<p>
{{ movie.plot }}
</p>
<button @click.prevent="remove(movie)" @keydown="remove(movie)">
Remove
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
It's not very pretty, but we're not here to enjoy the views.
Now write GraphQL queries (query for reading the data, mutation for writing/deleting the data and subscription to update the app whenever a change in the database is detected)
<script>
import axios from 'axios';
import gql from 'graphql-tag';
export default {
apollo: {
movies: {
query: gql`
query getMovies {
movies {
id
title
year
poster
plot
}
}
`,
update(data) {
return data.movies;
},
subscribeToMore: {
document: gql`
subscription mySubscription {
movies {
id
title
year
poster
plot
}
}
`,
updateQuery: (previousResult, { subscriptionData }) => {
return subscriptionData.data;
},
},
},
},
methods: {
remove(movie) {
this.$apollo.mutate({
mutation: gql`
mutation removeMovie($id: uuid!) {
delete_movies(where: { id: { _eq: $id } }) {
affected_rows
}
}
`,
variables: {
id: movie.id,
},
});
},
}
};
</script>
TADAA! If we didn't mess up our app then you should see your sample movies listed in your browser.
Wait, there's more! If you add or edit records in your database through the Hasura app you will instantly see the results in the Nuxt app because it's subscribed.