A GraphQL example

I’m designing REST API interface at my work. While researching on the subject, I found GraphQL which is an alternative to REST API. It looks certainly intriguing as I can customise the query to get the exact fields I want. Compared to REST API which gives back all the fields of an object, the response from GraphQL should be a bit smaller. This weekend I had some free time so I built a really simple server which implements GraphQL.

Code

I have a sqlite3 file which contains a list of countries and their corresponding 2 digit codes; I get these data from okfn.

In my schema, I have 1 type Country which consists of 3 fields id, name and code.

export const schema = buildSchema(`
  type Country {
    id: ID
    name: String
    code: String
  }
  type Query {
    country(name: String!): Country
    countries(limit: Int = 5): [Country]
  }
  type Mutation {
    addCountry(name: String!, code: String!): Country
  }
`);

I have 2 queries, country which returns a single country based on given name and countries which returns the first 5 countries by default;

Examples of queries would be something like:

{
  country(name: "yemen") {
    id
    name
    code
  }
}

#returns
#{
#  "data": {
#    "country": {
#      "id": "247",
#      "name": "Yemen",
#      "code": "YE"
#    }
#  }
#}

{
  countries(limit: 1) {
    id
    name
    code
  }
}

#returns
#{
#  "data": {
#    "countries": [
#      {
#        "id": "1",
#        "name": "Afghanistan",
#        "code": "AF"
#      }
#    ]
#  }
#}

You can also create a new country

mutation {
  addCountry(name: "hello", code: "word") {
    id
  }
}

#{
#  "data": {
#    "addCountry": {
#      "id": "256"
#    }
#  }
#}

You can find all my code at github.

Live

I enable graphiql on my server, so you can go to https://api.lttviet.com to check it out.

Experience

This is my very first node application so I did expect some troubles and dragons. And it came as no surprise that I got a lot of trouble debugging the codes. For example, I mistook == and === 1, null and undefined 2. Moreover, promise is a new concept to me which I’m still trying to wrap my head around.

Before creating this app, I have heard of ES2015 and I assumed that node had all ES6 covered. It was incorrect so I had to use babel with some plugins and presets to use the latest methods in ES2015 (import, export, async, await…).

From what I can tell, the 2 most popular modules to bundle my files for production are browserify or webpack. I didn’t have time to check either so I only used babel to compile my js files.

Todo

  • Caching: at the moment I’m not sure how effective this is compared to REST.
  • Pagination: countries has limit which can be set to any arbitrary number, which is pretty bad performance-wise
  • Errors: better error messages