Since our microservice is working with GraphQL, we would like to create a simple UI so that we can connect and expose the data we created and interact with it.
Vue.js is a progressive web framework for frontend applications that was created by Evan You. Vue.js stands out because of its simplicity in performing the same tasks as other frameworks.
The first step is to install Vue.js and the Vue.js CLIs:
$ npm install -g @vue/cli-init vue
After that, create a new project called client with the following command:
$ vue init webpack client
? Project name client
? Project description Order client
? Author Biharck Araujo <[email protected]>
? Vue build standalone
? Install vue-router? Yes
? Use ESLint to lint your code? Yes
? Pick an ESLint preset Standard
? Set up unit tests No
? Setup e2e tests with Nightwatch? No
? Should we run `npm install` for you after the project has been created? (recommended) npm
After the installation finishes, go to the client folder and start the application:
$ npm run dev
The application should be available at the following URL:
$ http://localhost:8080
Now, we will configure the dependencies to connect to order-ms with GraphQL. The following are the dependencies that we will need to configure:
- apollo-client: This is for connecting the client with GraphQL and also managing the state of the data
- vue-apollo: This is responsible for binding the data with the Vue.js application
- graphql-tag: This is for making the query and mutation to the backend
The following command is used to install these libraries:
$ npm install --save graphql vue-apollo apollo-client graphql-tag
With these libraries in place, we can move on and build the frontend. First, create a folder called src/graphql with a file named allOrders.js. This file will contain the GraphQL query for allOrders:
import gql from 'graphql-tag'
export const ALL_ORDERS_QUERY = gql`{
allOrders{
id,
userId,
quantity
}
}
`
After that, create a new file called src/apolloClient.js:
import { createBatchingNetworkInterface, ApolloClient } from 'apollo-client'
export const apolloClient = new ApolloClient({
networkInterface: createBatchingNetworkInterface({
uri: 'http://localhost:3000/graphql'
}),
connectToDevTools: true
})
This file will connect with our backend service using the apollo client library.
Create another file, called src/apolloProvider.js, with the following content:
import Vue from 'vue'
import VueApollo from 'vue-apollo'
import {apolloClient} from './apolloClient'
Vue.use(VueApollo)
export const apolloProvider = new VueApollo({
defaultClient: apolloClient,
defaultOptions: {
$loadingKey: 'loading'
}
})
Now, we are good to write the code to show the orders. Replace the HelloWorld.vue file with the following content:
<template>
<div>
<h4 v-if="loading">Loading......</h4>
<div v-for="order in allOrders" :key="order.id">
<router-link :to="order.id" exact>
<h3>Order:{{order.id}}</h3>
</router-link>
<p>
User: {{order.userId}}
Quantity:{{order.quantity}}
</p>
</div>
</div>
</template>
<script>
import { ALL_ORDERS_QUERY } from '../graphql/allOrders'
export default {
name: 'order',
data () {
return {
loading: 0,
allOrders: []
}
},
apollo: {
allOrders: {
query: ALL_ORDERS_QUERY
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>
Start the application and open it in a browser of your choice:
Now, let's create a new page to show the order by ID. Following the same idea as before, create a new file called src/graphql/listByOrderId.js with the following content:
import gql from 'graphql-tag'
export const ORDER_BY_ID = gql`
query orderById($id: ID!){
listByOrderId(id: $id){
userId,
quantity,
status,
complete
}
}`
Then, create the .vue page file called src/components/OrderById.vue:
<template>
<div>
<h3>UserID: {{listByOrderId.userId}}</h3>
<p>Quantity: {{listByOrderId.quantity}}</p>
<p>Status: {{listByOrderId.status}}</p>
<p>Complete: {{listByOrderId.complete}}</p>
</div>
</template>
<script>
import {ORDER_BY_ID} from '../graphql/listByOrderId'
export default {
data () {
return {
listByOrderId: {},
loading: 0
}
},
props: ['id'],
apollo: {
listByOrderId: {
query: ORDER_BY_ID,
variables () {
return {
id: this.id
}
}
}
}
}
</script>
Finally, add the route in src/router/index.js:
import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
import OrderById from '@/components/OrderById'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
name: 'HelloWorld',
component: HelloWorld
},
{
path: '/:id',
name: 'orderById',
component: OrderById,
props: true
}
]
})
When you click the Order Id on the web page, you will be redirected to the OrderById page:
The only thing that's missing is the order that we're creating, which we will implement. Create a file called createOder.js under src/graphql, with the following content:
import gql from 'graphql-tag'
export const ADD_ORDER = gql`
mutation addOrder($userId: Int!, $quantity: Int!, $status: String!, $complete: Boolean! ) {
createOrder(userId: $userId, quantity: $quantity, status: $status, complete: $complete ) {
userId,
quantity,
status,
complete
}
}
`
Add a component called AddOrder.vue:
<template>
<form>
<label for="userId">userId</label>
<br>
<input type="text" name="userId" v-model="userId">
<br>
<br>
<label for="quantity">Quantity</label>
<br>
<input type="text" name="quantity" v-model="quantity">
<br>
<label for="status">Status</label>
<br>
<input type="text" name="status" v-model="status">
<br>
<label for="complete">Complete</label>
<br>
<input type="text" name="complete" v-model="complete">
<br>
<button type="submit" @click="addOrder" >Add</button>
</form>
</template>
<script>
import { ADD_ORDER } from '../graphql/createOrder'
export default {
data () {
return {
userId: '',
quantity: '',
status: '',
complete: ''
}
},
methods: {
addOrder () {
console.log(this.userId, this.quantity, this.status, this.complete)
const userId = parseInt(this.userId)
const quantity = parseInt(this.quantity)
const status = this.status
const complete = this.complete === 'true'
this.$apollo.mutate({
mutation: ADD_ORDER,
variables: {
userId,
quantity,
status,
complete
}
})
this.$router.push('/')
}
}
}
</script>
Also, include the new route at src/router/index.js:
import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
import OrderById from '@/components/OrderById'
import AddOrder from '@/components/AddOrder'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/add',
name: 'AddOrder',
component: AddOrder
},
{
path: '/',
name: 'HelloWorld',
component: HelloWorld
},
{
path: '/:id',
name: 'orderById',
component: OrderById,
props: true
}
]
})
Go to the following URL:
http://localhost:8080/#/add
Then, create a new order with the parameters that are shown in the following screenshot and click on Add:
You will then see the details of the newly created order:
The following screenshot shows the created order: