Login | Register   
LinkedIn
Google+
Twitter
RSS Feed
Download our iPhone app
TODAY'S HEADLINES  |   ARTICLE ARCHIVE  |   FORUMS  |   TIP BANK
Browse DevX
Sign up for e-mail newsletters from DevX


advertisement
 

Introduction to Facebook GraphQL

Facebook GraphQL is an interesting development in the world of web applications and APIs that has been dominated by REST for years.


advertisement

GraphQL is a data query language used by Facebook since 2012 that was recently open sourced. It was designed to expose hierarchical data and make it easier for front-end developers to access it.

What does Facebook GraphQL look like?

Before diving in let's see an example of GraphQL:

{
  user(id: 3500401) {
    id,
    name,
    isViewerFriend,
    profilePicture(size: 50)  {
      uri,
      width,
      height
    }
  }
} 

The response would be:

{
  "user" : {
    "id": 3500401,
    "name": "Jing Chen",
    "isViewerFriend": true,
    "profilePicture": {
      "uri": "http://someurl.cdn/pic.jpg",
      "width": 50,
      "height": 50
    }
  }
} 

Note the format of the query. It is not JSON, but the response is JSON.



GraphQL Motivation and Properties

The motivation for GraphQL was various problems and deficiencies in the alternatives for accessing hierarchical data by front-end applications. Namely REST APIs and ad-hoc endpoints. Both of these approaches are unsuitable for applications that need a lot of flexibility when accessing the data. GraphQL has several other properties that distinguish it from REST APIs. It is not transport specific and in particular not HTTP specific. Each query is just a string. No HTTP verbs or headers are required. That makes it well suited both for public APIs over HTTP as well as high performance internal APIs using faster transports like TCP or even UDP. GraphQL is also strongly typed, which helps a lot in managing complex data.

The bottom line is that with GraphQL a client can request arbitrary subsets of data from a graph with complete control over the amount, level of detail and shape of the returned results.

GraphQL Type System

To support all that goodness, GraphQL uses schemas based on a type system. The type system is very rich and supports features such as inheritance, interfaces, lists, custom objects, enumerated types and specifying if individual values are nullable. Here is a sample Star Wars themed schema:

enum Episode { NEWHOPE, EMPIRE, JEDI }

interface Character {
  id: String!
  name: String
  friends: [Character]
  appearsIn: [Episode]
}

type Human : Character {
  id: String!
  name: String
  friends: [Character]
  appearsIn: [Episode]
  homePlanet: String
}

type Droid : Character {
  id: String!
  name: String
  friends: [Character]
  appearsIn: [Episode]
  primaryFunction: String
} 

The Episodes is an enumeration of Star Wars episodes. The Character interface defines fields that are common to every Character-based type. The id field is a non-nullable string (the ! means non-null). The name is a nullable string (may be name is not available). The friends field is a list of Characters and appearsIn is a list of Episodes.

There are two types based on Character: Human and Droid. They have all the fields of Character, but Human adds a homePlanet field and Droid adds a primaryFunction field. GraphQL Queries Queries in GraphQL can be pretty sophisticated. On the backend you can attach custom code to provide query functionality beyond just returning nested subsets of the data. For example here is an implementation in EcmaScript 2015 A.K.A ED6 that allows to query for the hero of an episode:

name: 'Query',
  fields: () => ({
    hero: {
      type: characterInterface,
      args: {
        episode: {
          description: 'If omitted, returns the hero of the whole saga. If ' +
                       'provided, returns the hero of that particular episode.',
          type: episodeEnum
        }
      },
      resolve: (root, { episode }) => getHero(episode),
    }, 

Note, the "args" which expects an episode, which is one of the enumeration values specified earlier and then the "resolve" key, which specifies a getHero() function that expects the episode as an argument.

Here is a simple implementation of the getHero() function:

export function getHero(episode) {
  if (episode === 5) {
    // Luke is the hero of Episode V.
    return luke;
  }
  // Artoo is the hero otherwise.
  return artoo;
} 

From the client-side you would invoke the query as:

query  {
  hero(episode(JEDI)) {
    name
  }
} 

The response would be:

{
  "data": {
    "hero": {
      "name": "R2-D2"
    }
  }
} 

Now, here is the cool part. Without any changes to the backend, you can run all kinds of variations on this query and ask for additional information about our hero.

For example, to also get the id and all the friends' use this query:

{
  hero(episode(JEDI)) {
    id
    name
    friends {
      id
      name
    }
  }
} 

The response would be something like:

{
  "data": {
    "hero": {
      "id": "2001",
      "name": "R2-D2",
      "friends": [
        {
          "id": "1000",
          "name": "Luke Skywalker"
        },
        {
          "id": "1002",
          "name": "Han Solo"
        },
        {
          "id": "1003",
          "name": "Leia Organa"
        }
      ]
    }
  }
} 

Validation

The schema can save a lot of grief to developers both on the backend and the frontend by automatically detecting invalid queries and responding with detailed error messages that point to the source of the problem. This is especially important when constructing large nested queries where just saying "Invalid Query" doesn't help the caller to figure out what's wrong and how to fix it.

Here is an example of an invalid query:

# INVALID: hero is not a scalar, so fields are needed
{
  hero
} 

Here is the response:

{
  "errors": [
    {
      "message": "Field \"name\" of type \"String\" must not have a
sub selection.",
      "locations": [
        {
          "line": 4,
          "column": 10
        }
      ]
    }
  ]
} 

Conclusion

GraphQL is an interesting development in the world of web applications and APIs that has been dominated by REST for years. It is still very young and there aren't any mature implementations outside of Facebook. Creating a GraphQL server appears to be a non-trivial undertaking and it's not clear at what scale it becomes useful.



   
Gigi Sayfan is the chief platform architect of VRVIU, a start-up developing cutting-edge hardware + software technology in the virtual reality space. Gigi has been developing software professionally for 21 years in domains as diverse as instant messaging, morphing, chip fabrication process control, embedded multi-media application for game consoles, brain-inspired machine learning, custom browser development, web services for 3D distributed game platform, IoT/sensors and most recently virtual reality. He has written production code every day in many programming languages such as C, C++, C#, Python, Java, Delphi, Javascript and even Cobol and PowerBuilder for operating systems such as Windows (3.11 through 7), Linux, Mac OSX, Lynx (embedded) and Sony Playstation. His technical expertise includes databases, low-level networking, distributed systems, unorthodox user interfaces and general software development life cycle.
Comment and Contribute

 

 

 

 

 


(Maximum characters: 1200). You have 1200 characters left.

 

 

Sitemap
Thanks for your registration, follow us on our social networks to keep up-to-date