Your first GraphQL API - Introduction

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.

In a nutshell, GraphQL provides a few significant benefits to making the life of API development easier:

  1. Ask for what you need, get exactly that.
  2. Get many resources in a single request.
  3. Describe what’s possible with a type system.
  4. Move faster with powerful developer tools.
  5. Evolve your API without versions.
  6. Bring your own data and code.

Head to official site if you want to read about more the benefits GraphQL brings for us. In this series of tutorials, we will start from the basics of building GraphQL API then slowly evolve to more advanced topics.

Setting the Goal

The library that we are going to use in these tutorials is Youshido/GraphQL. It is a package that will help us implement GraphQL without re-inventing the wheel. Youshido/GraphQL is a very well written and maintained project. Its excellent Object-Oriented design makes it super easy to implement GraphQL in OOP fashion and that is the main reason we have chosen to work with Youshido/GraphQL over other PHP GraphQL implementation.

We will be using the OOP fashion of Youshido/GraphQL across all tutorials. We believe OOP makes the code easy to maintain and simple to explain the concepts.

We are going to build a GraphQL API for a simple blog. This blog has a series of articles and each article belongs to an author. Features of our API provides include read, write, pagination, search and so on. To make these tutorials focused, we will skip stuff like user authentication, sophisticated business logic and other framework related stuff.

To keep things clear and focused, we are not going to use Database. However in reality, mostly you store articles and authors records in some sort of Database.

Just keep in mind, the whole purpose of these tutorials is to demonstrate how we can use the package Youshido/GraphQL to implement GraphQL for our own application.

Installing the Youshido/GraphQL package

Create a folder blog to hold our code sample.

Then we will install the Youshido/GraphQL package using Composer. Navigate to blog folder and run command as show below:

composer require youshido/graphql

Create three more sub-directories under src folder:

  • src/Repository: This directory stores some fake repositories that will give us some static articles and authors' records. As mentioned earlier, we are not going to use Database in these tutorials. These fake repository classes pretend to be your real repository classes.
  • src/Field: This directory stores Youshido/GraphQL Field classes.
  • src/Type: This direcotry stores Youshido/GraphQL Type classes.

We will use Composer to manage our own classes' auto-loading, add following content to the bottom of composer.json file:

{
...
    "autoload"
:
    {
        "psr-4"
    :
        {
            "StarTutorial\\"
        :
            "src"
        }
    }
}

Run the following command from your command line interface to refresh Composer loader:

Complete our fake repository classes by copying following content to their respective files:

src/Repository/ArticlesRepository.php:

<?php
namespace StarTutorial\Repository;
 
class ArticlesRepository
{
    public static function findAll()
    {
        return [
            [
                'id' => 1,
                'title' => 'My First GraphQL API',
                'content' => 'It is all about GraphQL',
                'created' => new \DateTime('2017-02-24 11:20:10'),
                'author_id' => 1,
            ],
            [
                'id' => 2,
                'title' => 'GraphQL History',
                'content' => 'GraphQL is created by Facebook',
                'created' => new \DateTime('2017-03-27 12:20:10'),
                'author_id' => 2
            ],
            [
                'id' => 3,
                'title' => 'GraphQL vs Rest',
                'content' => 'GraphQL is a query language, whereas Rest is a protocol',
                'created' => new \DateTime('2017-04-30 13:20:10'),
                'author_id' => 2
            ]
        ];
    }
}

src/Repository/AuthorsRepository.php:

<?php
namespace StarTutorial\Repository;
 
 
class AuthorsRepository
{
    public static function findAll()
    {
        return [
            [
                'id' => 1,
                'name' => 'Xu',
            ],
            [
                'id' => 2,
                'name' => 'Lee',
            ]
        ];
    }
}

Reading an article with ID

In a quick summary, GraphQL is a query language and it works by defining a schema that describes how and what data can be queried by clients.

There are two types of Operations in GraphQL:

  • Query: a read-only request that is not supposed to do any changes on the server.
  • Mutation: a request that changes(mutate) data on the server and followed by a data fetch.

We are going to create a Query that will allow us to read an article with its ID.

The first thing we need to do is to create an ArticleType class as shown below:

src/Type/ArticleType.php:

<?php
namespace StarTutorial\Type;
 
 
use Youshido\GraphQL\Type\NonNullType;
use Youshido\GraphQL\Type\Object\AbstractObjectType;
use Youshido\GraphQL\Type\Scalar\DateTimeType;
use Youshido\GraphQL\Type\Scalar\IntType;
use Youshido\GraphQL\Type\Scalar\StringType;
 
class ArticleType extends AbstractObjectType
{
    public function build($config)
    {
        $config->addFields([
            'id' => new NonNullType(new IntType()),
            'title' => new StringType(),
            'content' => new StringType(),
            'created' => new DateTimeType(),
            'author_id' => new NonNullType(new IntType())
        ]);
    }
 
}

Type classes in Youshido/GraphQL define the fields and their values' types that a Type possesses.

Next, we need to do is to create an ArticleField class as shown below:

src/Field/ArticleField.php:

?

<?php
 
namespace StarTutorial\Field;
 
 
use StarTutorial\Repository\ArticlesRepository;
use StarTutorial\Type\ArticleType;
use Youshido\GraphQL\Config\Field\FieldConfig;
use Youshido\GraphQL\Execution\ResolveInfo;
use Youshido\GraphQL\Field\AbstractField;
use Youshido\GraphQL\Type\Scalar\IntType;
 
class ArticleField extends AbstractField
{
    public function getType()
    {
        return new ArticleType();
    }
 
    public function build(FieldConfig $config)
    {
        $config->addArgument('id', new IntType());
    }
 
    public function resolve($value, array $args, ResolveInfo $info)
    {
        $all = ArticlesRepository::findAll();
 
        foreach ($all as $single) {
            if ($single['id'] == $args['id']) {
                return $single;
            }
        }
 
        return null;
    }
}

Field classes in Youshido/GraphQL will resolve users' request and respond with data types defined above in Type classes. We also define acceptable arguments in Field classes.

Lastly, we will define a schema attached with ArticleField. Meanwhile, we will create a simple request to our own schema right from PHP:

Create a new file tutorial-introduction.php:

<?php
 
    use StarTutorial\Field\ArticleField;
    use Youshido\GraphQL\Execution\Processor;
    use Youshido\GraphQL\Schema\Schema;
    use Youshido\GraphQL\Type\Object\ObjectType;
 
    require_once 'vendor/autoload.php';
 
    $processor = new Processor(new Schema([
        'query' => new ObjectType([
            'name' => 'RootQueryType',
            'fields' => [
                new ArticleField()
            ]
        ]),
    ]));
 
    $processor->processPayload('{ article(id:2){id,title} }');
 
    echo '<pre>';
    echo json_encode($processor->getResponseData()) . "\n";
    echo '<pre>';

Access the page from the browser of your choice via the URL http://your-local-php-server/tutorial-introduction.php.

You should expect a JSON output as shown below if you have followed this tutorial correctly:

{
"data": {
    "article": {
        "id": 2,
        "title": "GraphQL History"
        }
    }
}

Try to change the ID argument or add other fields, see how GraphQL gives you exactly what you ask.

The End

Now we have set our goal clearly and had our first simple GraphQL end point. Next tutorial, we will implement a Field that can resolve a list of articles and explain how we can accomplish pagination in Youshido/GraphQL. If you like our post, please follow us on Twitter and help spread the word. We need your support to continue. If you have questions or find our mistakes in above tutorial, do leave a comment below to let us know.