# GraphQL

# What is it?

A query language for your API

TIP

GraphQL is a query language for APIs and a runtime for fulfilling those queries with your existing data. GraphQL provides a complete and understandable description of the data in your API, gives clients the power to ask for exactly what they need and nothing more, makes it easier to evolve APIs over time, and enables powerful developer tools.

You can learn more here: graphql.org (opens new window)

TIP

🚀 Vue Apollo integrates GraphQL in your Vue.js apps!

The integration we are about to use for GraphQL is only for queries. It also knows about mutations and subscriptions but we are not going to use them for this workshop.

The sample graphQL enpoint we will use is based on this one: JsNoise GraphQL playground (opens new window) In the left window just add the following and click the Play icon:

{

  show(id:200){title}
  
  showsList(page:32){ first, last, shows{ id title producerName, mp3}}
  
}

For the GraphQL integration with apollo we have to import it into our project. We do this by simply pressing "Add Dependency". In the search box look for vue-apollo the version created by Akryum, graphql created by graphql and apollo-boost and graphql-tag by apollographql.

With the apollo added we now have to update the main.js file to configure and use it.

import ApolloClient from 'apollo-boost'

const apolloClient = new ApolloClient({
    uri: 'https://jsnoise.herokuapp.com/graphql'
});

import VueApollo from 'vue-apollo'
import gql from "graphql-tag";

Vue.use(VueApollo)

//The provider holds the Apollo client instances that can then be used by all the child components.
const apolloProvider = new VueApollo({
    defaultClient: apolloClient,
})

Once the provider was created we have to add it to Vue so that it knows about it. We do this by updating the new Vue({...}) as follows:

new Vue({
    router,
    store,
    apolloProvider,
    render: h => h(App)
}).$mount("#app");

It is time for the first GraphQL query!

Let's first rename the existing action loadPodcasts with loadPodcastsREST. This way we'll keep for reference the REST version and maybe compare it with the GraphQL one. Next let's add a new action loadPodcasts like this:

loadPodcasts({ commit, state }) {
    apolloClient
        .query({
        query: gql`
            query shows($page: Int) {
            showsList(page: $page) {
                first
                last
                shows {
                id
                title
                mp3
                publishedDate
                producerName
                producerId
                }
            }
            }
        `,
        variables: { page: state.page }
        })
        .then(response => {
        commit("LOAD_PODCASTS", response.data.showsList);
        })
        .catch(err => console.dir("gql err: ", err));
},

The above action looks a little bit more complex than the REST one but there are reasons. One of the reasons is that in a graphql query you can specify multiple requests for data that are executed in 1 trip to the server. Another one is that you can specify for multiple resources what fields you want back. The reality is that for a REST query is all or nothing, all the fields and only one resource per request.

Let's come back to our query. We are using the apolloClient we defined in the begining and on it we are calling a query method. Inside the method we send an object that has a propery named query. The property expects a graphQL query so we use the gql from graphql-tag. In the query we need to send some parameters and we do that by wraping the original query in a new query that can receive parameters. The parameters are defined with $ in front of it and with a type. Once we have the wrapped arround query we can use the parameters defined for the graphql query. We also specify the exact fields that we want back. With the query defined and the parameters set up we have to tell the apollo client what values to use for the parameters. We do this inside the variables block of the query.

We also need to query for the podcast details and we'll do this by first renaming the loadPodcast action to loadPodcastREST just for reference.

Le't add and describe a new action, GraphQL in nature, with the name loadPodcast:

loadPodcast({ commit, state }, showId) {
        apolloClient
            .query({
            query: gql`
                query oneShow($id: Int!) {
                show(id: $id) {
                    id
                    title
                    mp3
                    description
                    producerName
                    publishedDate
                }
                }
            `,
            variables: { id: showId }
            })
            .then(response => {
            commit("LOAD_PODCAST", response.data.show);
            })
            .catch(err => console.dir("gql err: ", err));
}

The above action will use apollo client to make a qraphql query to our backend. It is using the gql method to prepare the query and to use the parameter for the id of the podcast. It specifyies the fields it expects to get back and then makes a call to the mutation LOAD_PODCAST to set the show data.

As you can see GraphQL offers advantages that are to be looked into carefully because it might just be a better alternative than REST.

# Well done! you now have Flux architecture in place.

Next, let's just make it public by doing a deploy to netlify.