Getting started
Beforehand, it is important to know that this library does not provide a standalone solution. As such, some amount of PHP knowledge is required, and ideally a Web framework should encapsulate the GraphQL endpoint (such as Laravel, Slim or Symfony). All you truly need is a way to read and write PSR-7 objects from/to the client. Afterwards, you can handle incoming HTTP requests as GraphQL requests.
Requirements
- A project with an initialized composer.json
- A project with an initialized package.json and Gruntfile.js
- Some way to read and write PSR-7 request objects to/from the client
- An endpoint dedicated to GraphQL
Implementation
Assuming you have all three things above, the first thing to do would be to include both the GraphQL Generator and the GraphQL Framework.
composer require kronostechnologies/graphql-framework
composer require --dev kronostechnologies/graphql-generator
Once this is done, your PHP dependencies are setup. Next thing, we need a package from npm in order to generate the GraphQL schema for us:
npm install --save-dev grunt-graphql-php-generator
Setting up a schema watcher
Now that all the dependencies are installed, you can create your first .graphqls
schema. Let's create it at a specific location to simplify the example, under graphql/schema.graphqls
:
scalar DateTime
scalar Cursor
interface Identifiable {
id: ID
}
enum Color {
BLUE,
RED,
YELLOW,
GREEN,
PURPLE,
CYAN
}
type Item implements Identifiable {
id: ID,
name: String,
color: Color
}
type Query {
item(id: ID): Item!
items(page: Int, perPage: Int): [Item!]!
}
Once created, you will need to adjust your Gruntfile to tell it from which file to generate the schema from/to. Add this to your Gruntfile.js
:
'autogen-schema': {
options: {
source: './graphql/schema.graphqls',
destination: './[BaseFolder]/GraphQL/Schema/',
generatorCmdPath: './vendor/bin/graphqlgen',
namespace: '[BaseNamespace]',
deleteAndRecreate: true,
runPHPCSFixer: true
}
}
Now, you can run a Grunt command to generate the files required by the framework for you:
grunt autogen-schema
Entry point
The entry point requires access to a PSR-7 request object, and it will respond in a PSR-7 response. The core requirement to handle a GraphQL is the following:
$configuration = GraphQLConfiguration::create()
->setControllersDirectory(__DIR__ . '\\[BaseNamespace]\\GraphQL\\Controllers')
->setGeneratedSchemaDirectory(__DIR__ . '\\[BaseNamespace]\\GraphQL\\GeneratedSchema');
// Assume $request contains the PSR-7 request.
$entryPoint = new HttpEntryPoint($configuration);
$response = $entryPoint->executeRequest($request);
// $response contains the PSR-7 response
You should now be able to query the GraphQL entry point. It will give out its introspection result, but it won't execute any query successfully since we have defined no controller yet.
Query controller
Let's define a sample query controller to get a single item. It should be located under [BaseDirectory]\GraphQL\Controllers
. Since we want to get the item
field in the Query
type defined in the schema higher up, we need a QueryController
:
<?php
class QueryController extends BaseController {
public function getItem() {
return $this->hydrator->fromSimpleArray(ItemDTO::class, [
'id' => $this->context->getArgument('id'),
];
}
}
Here, we simply return an ItemDTO
, which is the representation of what querying Item
in an object. These DTOs are made by the generator to aid in development mostly.
Now, the following query should work:
query {
item(id: 1) {
id
}
}