First time I heard about this CSS library called Tachyons was during my technical interview at Rangle.io Inc. 👨💼I said that I’m best familiar with Bootstrap, but I have also worked a little bit…
GraphQL is a query language for your API, and a server side runtime for executing queries. A single endpoint can return data about multiple resources, which makes it a great fit for Vue.js single page applications.
This article will go over how to build a GraphQL API from scratch, as well as define and implement queries and mutations with custom types. I will use Node.js for the GraphQL server, and make requests and display the results using a Vue.js single page application.
A GraphQL service is created by defining types and fields, then providing functions for each field on each type. The canonical example from the GraphQL documentation is:
The above is how we implement a query, custom type, and endpoint using GraphQL. The matching client side query looks like this:
which returns:
Install the vue-cli by running:
Create a new project by running:
and go with the default by choosing ❯ default (babel, eslint)
. A ton of nod e modules will be installed. We also need to create a folder for the API server, so run the following after cd
into the project (cd graphql-example
)
Let’s setup up a simple query to make sure everything is working, and see what a GraphQL server looks like. Inside of server/index.js
, require some modules:
The next thing to do is define the schema — what types of queries and types the server will use. Our first schema is basically the “hello world” of GraphQL:
We define a Query type called language
. It returns a String
. GraphQL is statically typed — fields have types, and if something doesn’t match up, and error is thrown.
Unlike REST APIs, Graph APIs have just one endpoint, which responds to all requests. This is called a resolver. I’ll call mine rootValue
, and include the implementation for the language
query:
language
just returns a String
. If we returned a different type, for example 1
or {}
, an error would be thrown, since when we declared language
in the schema, we specified a String
would be returned.
The last step is to create the express app, and mount the resolver, rootValue
, and schema
.
Let’s now implement the client side Vue app, that will make the request.
Head over to src/App.vue
, and delete the boilerplate. It should now looks like this:
We also import axios
, which we will use to make the HTTP requests.
By default, graphqlHTTP
listens for POST
requests. According to the recommendations in serving over HTTP, we should include the query
and variables
in the body of the request. This will lead us to the following request:
The query should be inside curly braces. Adding a button to trigger the request, and a variable to save the result, we end up with:
Clicking “Get Language” should return and render the result.
Ok, great. So far we:
What else can we do with GraphQL?
GraphQL lets us define custom types, and objects to represent them in the target language — in this case, JavaScript, but there are GraphQL clients for most server side languages. I will define a Champion
type in the schema, and matching ES6 class to store any properties and methods.
Firstly, update the schema:
Nothing too exciting other than a new type, Float
. Next we can define an ES6 class to represent this type, and store any instance methods or additional data. I’ll define this in a new file, server/champion.js
.
Nothing special, just a ES6 class. Note we have name
and attackDamage
— the same fields defined in the schema for Champion
.
Now, let’s create another query that uses the Champion
type. The updated schema
is as follows:
getChampions
returns an array of Champion
. Great! To finish this example off, some mock data and another endpoint:
Restart the server by pressing ctrl+c
in the terminal running the server, and run node server
again. Let’s verify if this is working, by sending a query from the client.
Querying getChampions
is a little more interesting than language
. This time the result will contain the user defined Champion
type — and whatever fields we ask for. GraphQL requires us to be explicit in which fields we want. For example the following query:
will not work. At least one field should be specified. The updated query:
Returns:
Notice only the name is returned! If we included attackDamage
, we would get that too. The query:
and response:
Implementing this in the Vue app is equally straightforward:
Make sure you restart the server with node server
, if you didn’t already. No need to restart the Vue app, since webpack’s hot reload will automatically update when you save any changes.
Clicking “Get Champions” yields:
getChampions
return all champions. GraphQL also supports passing arguments, to return a subset of data. This requires:
Let’s implement a getChampionByName
query. As usual, start with the query definition:
Notice we declare the argument name
, and the type String!
. The !
means the argument is required.
Next, the implementation:
Nothing too exciting — we just use find
to get the corresponding champion. An improvement would be to add some error handling, and compare name
disregarding case.
Now, the client side implementation. This is where things get a bit more interesting. When passing arguments, we should name the query, and declare the arguments with the corresponding type:
Line by line:
Some extra markup will let us display the result in the Vue app (don’t forget to restart the GraphQL server):
So far, we have just been fetching data. You will often want to update data, too, which is why GraphQL also provides mutations. The syntax and implementation isn’t too far from what we covered so far. Let’s start with by defining the mutation:
Mutations goes in a Mutation
type. The rest of the syntax should be familiar by this point. We are returning the updated record, a Champion
type. The implementation is equally straightforward:
In a more realistically example, you might execcute an SQL query to update a record in a database, or do some validation. We have to return a Champion
type, since we specified so in the mutation declaration. GraphQL will automatically select the correct fields to return, based on the request — we will ask for the name
and updated attackDamage
, so shown below:
The only real difference here is we declared the operation name to be a mutation
type instead of a query
type.
The fully updated example is as follow:
As usual, restart the GraphQL server. The result is as follows:
You can click “Get Champion”, and see if the data was saved correctly (it should return the newly updated attack damage):
I did not go over testing. However, testing the server side endpoints is esay, since it’s just plain JavaScript — just export the rootValue
object, and tests the functions like you normally would. I’ll explore testing a GraplQL API in a future post.
Running a security program can be an overwhelming task. There are so many factors to consider including: encryption, application security, disaster recovery and let’s not forget adherence to…
I had removed braces three years ago. I had this habit of visiting this small self service hotel nearby whenever I went for a teeth checkup. It was kind of a tradition for me, eat something from…
After tens of thousands of words of fiction, poetry and quite a bit of non fiction I think the time is ripe for one of my meta articles you all appear to love so much. So let’s ‘cut right to the…