Using GraphQL in OpenFaaS functions

This is the first of a series of articles in which I'll be covering how to use the GraphQL query language to build functions and deploy them on OpenFaaS.

Background

I'll assume you have some experience using GraphQL, if not go to the official page, don't forget to check how to use it with your favorite language here, then come back.

Let's start with the basics

I'll use the example for JavaScript found at the GraphQL docs.

  1. Create a folder and change to it
$ mkdir graphql01 && cd graphql01
  1. Install graphql module
$ npm install graphql
  1. Copy the code below to a file named hello.js
const { graphql, buildSchema } = require('graphql');

// schema
const schema = buildSchema(`
type Query {
	hello: String
}
`);

// resolver
const root = { hello: () => 'Hello world!' };

// query
const query = '{ hello }';

// call the graphql engine
graphql(schema, query, root)
	.then(response => { console.log(response); });
  1. Run the code
$ node hello.js
{ hello: 'Hello world!' } }

Now the OpenFaaS version

As we will be using the plain engine it's not tied to any invocation method, so we can try it with the standard node template as with the new node10-express template. Let's do it.

Standard Node template

Before all create a folder and get into it

  1. Create a new project using faas-cli using the standard node template, replace padiazg with your user for the Docker Hub, or the address of your private registry if you have one.
$ faas-cli new graphql01 --lang node --prefix padiazg
  1. Modify handler.js to match the code below
"use strict"
const { graphql, buildSchema } = require('graphql');

// schema
const schema = buildSchema(`
  type Query {
    hello: String
  }
`);

// resolver
const root = { hello: () => 'Hello world! from OpenFaaS' };

module.exports = (context, callback) => {
    
    // here we call the graphql engine, the query is expected to come in 
    // the context parameter
    graphql(schema, context, root)
        .then( response => { callback(undefined, response); })
        .catch(err => { callback(err, undefined); })
        ;
}
  1. Take care of dependencies
    At this point you can go to the folder where handler.js lies and do a npm i --save graphql, or edit the package.json and add this:
   ...
  "dependencies": {
	...
    "graphql": "^14.0.2"
  }
  ...
  1. Deploy the function using
$ faas-cli up -f graphql01.yml

After the node10-espress example we'll cover how to do some tests, if you are impatient you can check that section now before continue.

Node10-express template

As the previous example, create a folder an go into it.

  1. Pull the template. You can actually use any of the both node-express templates, but we will use the newer one.
$ faas-cli template pull https://github.com/openfaas-incubator/node10-express-template
  1. Create a new project using faas-cli using the node10-express template, replace padiazg with your user for the Docker Hub, or the address of your private registry if you have one.
$ faas-cli new graphql02 --lang node10-express --prefix padiazg
  1. Update handler.js with this code:
"use strict"

const { graphql, buildSchema } = require('graphql');

const schema = buildSchema(`
  type Query {
    hello: String
  }
`);

const root = { hello: () => 'Hello world! from OpenFaaS' };

module.exports = (event, context) => {
    graphql(schema, event.body, root)
        .then( response => {
            context
                .status(200)
                .succeed(response);
        })
        .catch(err => {
            context
                .status(500)
                .fail(response);
        });
}
  1. Take care of dependencies
    Same procedure than the prior example, at the same folder where handler.js is run npm i --save graphql, or edit the package.json and add this:
   ...
  "dependencies": {
	...
    "graphql": "^14.0.2"
  }
  ...
  1. Deploy the function using
$ faas-cli up -f graphql02.yml

Test your function

We can test the functions we just deployed by several ways, next I'll use the one you like.

Using the Portal

Locate one of the functions and use { hello } as request body.

Using faas-cli

$ echo { hello } | faas-cli.exe invoke graphql01

Using curl

$ curl -X POST --data-ascii '{ hello }' http://localhost:31112/function/graphql02

You should get something like this

{"data":{"hello":"Hello world! from OpenFaaS"}}

A few words about the format of the result

The GraphQL engine always returns a json with either a dataor error attribute.

If the query was successful data contains result of it.

{
	"data": {
		"hello":"Hello world! from OpenFaaS"
	}
}

In the other hand, if something went wrong during the execution of the query, and the engine could catch it, an error attribute will be returned with some information about the exception.

As an example we can simulate we misspelled out object, and see what comes back

$ echo "{hell}" | faas-cli invoke graphql02 --gateway=http://localhost:31112 | python -m json.tool
{
    "errors": [
        {
            "locations": [
                {
                    "column": 2,
                    "line": 1
                }
            ],
            "message": "Cannot query field \"hell\" on type \"Query\". Did you mean \"hello\"?"
        }
    ]
}

Conclusion

I hope that with this simple examples you could start using GraphQL with this amazing platform that OpenFaaS is. As you can see, it's not so difficult.
In next articles I'll cover some more elaborated examples, as the ability to be able to answer queries for more than one object, as well as regarding parameters, pros and cons, and other aspects that will come in mind later.

I you have any question or suggestion you an reach me by email (padiazg@gmail.com), or comment below.

Using GraphQL in OpenFaaS functions
Share this