If you’ve been keeping up, you’ll know that I’ve been writing a sort-of mega series around developing with GraphQL and Couchbase. In past tutorials we’ve explored how to use GraphQL with Java, how to use GraphQL with Node.js, and how to use GraphQL with Golang.

After I had produced content around all those languages, someone on my team had asked me where PHP was in the mix. From that comment spawned this tutorial regarding creating an API with GraphQL and PHP using Couchbase NoSQL as the data layer.

Before getting too invested in this GraphQL PHP and NoSQL tutorial, there are a few assumptions that must be met:

  1. Couchbase must have already been installed and configured.
  2. PHP must have been installed and configured.
  3. Composer and PECL must be available for downloading PHP project dependencies.

Assuming the above conditions are met, we can proceed to developing our application.

Creating a New Project with GraphQL and Couchbase Dependencies for PHP

The first step towards the success of our project is to create one and download the necessary dependencies. Somewhere on your computer, create a new directory and include a graphql.php file. Using your command prompt within this directory, execute the following:

The above command will install our GraphQL dependency that does all of the heavy lifting for our API. Next, execute the following command from your command prompt:

The above command will install the Couchbase PHP SDK. Reiterating on my previous assumptions, you need to have Composer and PECL available to you.

More information on the Couchbase PHP SDK and the GraphQL package can be found in each of their respective documentations.

Configuring the Project for GraphQL and Couchbase Development

With the project created and the dependencies downloaded, we can work towards bootstrapping our application. Open the project’s graphql.php file and include the following:

In the above code we are referencing our Composer dependency and including a few of the GraphQL classes that we plan to use. Without actually configuring GraphQL or using our database, we need to establish a connection to our database.

My PHP application was running locally alongside my instance of Couchbase. Make sure to fill in the gaps when it comes to your own Couchbase connection information.

Defining GraphQL Objects for Data Management

Now we can focus on defining our data model, otherwise referred to as GraphQL objects within our API. For this particular example we’re going to be referencing Pokemon data. For this reason we might have information about a particular Pokemon, what moves it has, or what video game it is found in. This is going to be the basis of our data model.

Let’s start with the following in our graphql.php file using this example:

In the above code we have two objects with the possible JSON properties, also called fields. For the $pokemonType object, we have a field that references our other object. The listOf type means that we can expect an array of data to be returned.

The two objects that we have are far from as complex as they could be, but they serve a realistic example. However, as of now they are nothing more than a model blueprint. We need to be able to populate them with actual data from our database.

Developing Queries to Populate GraphQL Objects

The next step is to come up with queries to be executed against our database which will fill our GraphQL objects. This is done through queries, which at the end of the day is nothing more than another GraphQL object that contains logic.

Take the following code for example:

The above code, which would end up in your graphql.php file, has two possible queries. The first query called pokemons will return an array of the $pokemonType model. The resolve function is what actually runs the logic. The logic for pokemons will run a Couchbase N1QL query and return the result. The result of the N1QL query is mapped to each of the fields defined in our GraphQL object.

Executing the pokemons query might look something like this:

The pokemon query is similar, but not the same. In the pokemon query, we are requiring an id be passed. This id value is used to do a direct lookup for a particular NoSQL document rather than a NoSQL query.

The pokemon query might look something like this:

The result of this query will be a single object rather than an array.

Handling Model Relationships in a Simplistic Fashion

Now let’s say that we wanted some kind of data relationship. As of now we’ve assumed that move data and Pokemon data exist in the same document, but what if we had data that was split up, but related?

There are two approaches to this:

  1. We can do a JOIN query making potentially more complex queries to manage.
  2. We can modularize the queries on a per field basis keeping them small and slick.

If you had a chance to listen to my podcast titled GraphQL for API Development which featured GraphQL co-creator Lee Byron, you’ll know that neither of these are wrong and it comes down to preference. Let’s take a look at the latter where we modularize the queries and GraphQL objects.

Let’s say we now want to include game data and it is a separate object like this:

Now let’s say that our Pokemon documents in our database contain a game id, but not the actual data. Similar to a primary and foreign key relationship, but not really because this is NoSQL.

What we could do now is the following:

Notice that we’ve changed our $pokemonType to include a game field, but this field has its own resolve function. Inside this resolve function, we can access the parent or $root data which contains a game id, because that is what our pokemon and pokemons queries gave us. Using the id, we can get the game data that exists in a separate document and return it.

Now our original pokemons query is spared from a JOIN statement. I’m not saying a JOIN statement is bad, but imagine if your had some wild data models that required a 50 line query. In those scenarios it might make sense to break it up rather than try to maintain a massive query. As a fun fact, the game operation on the database won’t be called unless the game field is requested in a GraphQL query from the frontend.

Bringing the Application Together

It is time to bring the application together. As of now we’ve only seen the data models and queries, but we haven’t configured it for use with GraphQL.

Take a look at the now complete code:

The bottom half of the code was taken from the PHP GraphQL server official documentation. Essentially we’re defining our queries as the schema and taking in any input from the end user. This input is used in combination with the schema to produce a result that is returned to the user.

Conclusion

You just saw how to create a GraphQL API with PHP and Couchbase as the NoSQL database. GraphQL is a great alternative to writing RESTful APIs because it allows you to properly maintain a data model that can be queries via a frontend. This reduces the amount of HTTP requests as well as the payload returned in any request.

If you’d like to learn more about using Couchbase with PHP, check out a previous tutorial I wrote titled, Getting Started with NoSQL Using Couchbase Server and PHP.

Author

Posted by Nic Raboy, Developer Advocate, Couchbase

Nic Raboy is an advocate of modern web and mobile development technologies. He has experience in Java, JavaScript, Golang and a variety of frameworks such as Angular, NativeScript, and Apache Cordova. Nic writes about his development experiences related to making web and mobile development easier to understand.

Leave a reply