mirror of
https://github.com/retailcrm/graphql-php.git
synced 2024-11-22 04:46:04 +03:00
Work in progress on better docs
This commit is contained in:
parent
e4fa881cc3
commit
f9740c5f2c
182
docs/getting-started.md
Normal file
182
docs/getting-started.md
Normal file
@ -0,0 +1,182 @@
|
|||||||
|
# Installation
|
||||||
|
|
||||||
|
Using [composer](https://getcomposer.org/doc/00-intro.md):
|
||||||
|
add `composer.json` file to your project root folder with following contents:
|
||||||
|
```
|
||||||
|
{
|
||||||
|
"require": {
|
||||||
|
"webonyx/graphql-php": "^0.8"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
and run `composer install`.
|
||||||
|
|
||||||
|
If you already have composer.json file - simply run: `composer require webonyx/graphql-php`
|
||||||
|
|
||||||
|
If you are upgrading, see [upgrade instructions](https://github.com/webonyx/graphql-php/blob/master/UPGRADE.md)
|
||||||
|
|
||||||
|
# Install Tools (optional)
|
||||||
|
While it is possible to communicate with GraphQL API using regular HTTP tools it is way
|
||||||
|
more convenient for humans to use [GraphiQL](https://github.com/graphql/graphiql) - an in-browser
|
||||||
|
ide for exploring GraphQL APIs.
|
||||||
|
|
||||||
|
It provides syntax-highlighting, auto-completion and auto-generated documentation for
|
||||||
|
GraphQL API.
|
||||||
|
|
||||||
|
The easiest way to use it is to install one of the existing Google Chrome extensions:
|
||||||
|
|
||||||
|
- [ChromeiQL](https://chrome.google.com/webstore/detail/chromeiql/fkkiamalmpiidkljmicmjfbieiclmeij)
|
||||||
|
- [GraphiQL Feen](https://chrome.google.com/webstore/detail/graphiql-feen/mcbfdonlkfpbfdpimkjilhdneikhfklp)
|
||||||
|
|
||||||
|
Alternatively you can follow instructions on [GraphiQL](https://github.com/graphql/graphiql)
|
||||||
|
page and install it locally.
|
||||||
|
|
||||||
|
|
||||||
|
# Hello World
|
||||||
|
Let's create type system that will be capable to process following simple query:
|
||||||
|
```
|
||||||
|
query {
|
||||||
|
echo(message: "Hello World")
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
To do so we need an object type with field `echo`:
|
||||||
|
|
||||||
|
```php
|
||||||
|
<?php
|
||||||
|
use GraphQL\Type\Definition\ObjectType;
|
||||||
|
use GraphQL\Type\Definition\Type;
|
||||||
|
|
||||||
|
$queryType = new ObjectType([
|
||||||
|
'name' => 'Query',
|
||||||
|
'fields' => [
|
||||||
|
'echo' => [
|
||||||
|
'type' => Type::string(),
|
||||||
|
'args' => [
|
||||||
|
'message' => Type::nonNull(Type::string()),
|
||||||
|
],
|
||||||
|
'resolve' => function ($root, $args) {
|
||||||
|
return $root['prefix'] . $args['message'];
|
||||||
|
}
|
||||||
|
],
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
```
|
||||||
|
|
||||||
|
Same could be written as separate class:
|
||||||
|
|
||||||
|
```php
|
||||||
|
<?php
|
||||||
|
namespace MyApp\Type;
|
||||||
|
|
||||||
|
use GraphQL\Type\Definition\ObjectType;
|
||||||
|
use GraphQL\Type\Definition\Type;
|
||||||
|
|
||||||
|
class QueryType extends ObjectType
|
||||||
|
{
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$config = [
|
||||||
|
// Note: name is not required in this form, as it will be inferred
|
||||||
|
// from className ("Type" suffix will be dropped)
|
||||||
|
'fields' => [
|
||||||
|
'echo' => [
|
||||||
|
'type' => Type::string(),
|
||||||
|
'args' => [
|
||||||
|
'message' => Type::nonNull(Type::string()),
|
||||||
|
],
|
||||||
|
'resolve' => function ($root, $args) {
|
||||||
|
return $root['prefix'] . $args['message'];
|
||||||
|
}
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
parent::__construct($config);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Or for those who prefer composition over inheritance:
|
||||||
|
```php
|
||||||
|
<?php
|
||||||
|
namespace MyApp\Type;
|
||||||
|
|
||||||
|
use GraphQL\Type\Definition\Type;
|
||||||
|
use GraphQL\Type\DefinitionContainer;
|
||||||
|
|
||||||
|
class QueryType implements DefinitionContainer
|
||||||
|
{
|
||||||
|
private $definition;
|
||||||
|
|
||||||
|
public function getDefinition()
|
||||||
|
{
|
||||||
|
return $this->definition ?: ($this->definition = new \GraphQL\Type\Definition\ObjectType([
|
||||||
|
'name' => 'Query',
|
||||||
|
'fields' => [
|
||||||
|
'echo' => [
|
||||||
|
'type' => Type::string(),
|
||||||
|
'args' => [
|
||||||
|
'message' => Type::nonNull(Type::string()),
|
||||||
|
],
|
||||||
|
'resolve' => function ($root, $args) {
|
||||||
|
return $root['prefix'] . $args['message'];
|
||||||
|
}
|
||||||
|
],
|
||||||
|
],
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The interesting piece here is `resolve` option of field definition. It is responsible for retuning
|
||||||
|
value for our field. **Scalar** values will be directly included in response while **complex object**
|
||||||
|
values will be passed down to nested field resolvers (not in this example though).
|
||||||
|
|
||||||
|
Field resolvers is the main mechanism of **graphql-php** to bind type system with your
|
||||||
|
underlying data source.
|
||||||
|
|
||||||
|
Now when our type is ready, let's create GraphQL endpoint for it `graphql.php`:
|
||||||
|
|
||||||
|
```php
|
||||||
|
<?php
|
||||||
|
use GraphQL\GraphQL;
|
||||||
|
use GraphQL\Schema;
|
||||||
|
|
||||||
|
$schema = new Schema([
|
||||||
|
'query' => $queryType, // or new MyApp\Type\QueryType()
|
||||||
|
]);
|
||||||
|
|
||||||
|
$rawInput = file_get_contents('php://input');
|
||||||
|
|
||||||
|
try {
|
||||||
|
$rootValue = ['prefix' => 'You said: '];
|
||||||
|
$result = GraphQL::execute($schema, $rawInput, $rootValue);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$result = [
|
||||||
|
'error' => [
|
||||||
|
'message' => $e->getMessage()
|
||||||
|
]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
header('Content-Type: application/json; charset=UTF-8');
|
||||||
|
echo json_encode($result);
|
||||||
|
```
|
||||||
|
|
||||||
|
Our example is ready. Try it by running:
|
||||||
|
```sh
|
||||||
|
php -S localhost:8000 graphql.php
|
||||||
|
curl http://localhost:8000 -d "query { echo(message: \"Hello World\") }"
|
||||||
|
```
|
||||||
|
|
||||||
|
Or grab the full [source code](https://github.com/webonyx/graphql-php/blob/master/examples/00-hello-world).
|
||||||
|
Obviously hello world only scratches the surface of what is possible.
|
||||||
|
So check out next example, which is closer to real-world apps.
|
||||||
|
|
||||||
|
Or just keep reading about [type system](types/) definitions.
|
||||||
|
|
||||||
|
# Blog example
|
||||||
|
It is often easier to start with full-featured example and then get back to documentation
|
||||||
|
for your own work.
|
||||||
|
|
||||||
|
Check out [Blog example of GraphQL API](https://github.com/webonyx/graphql-php/tree/master/examples/01-blog).
|
||||||
|
It is quite close to real-world GraphQL hierarchies. Follow instructions and try it yourself in ~10 minutes.
|
81
docs/index.md
Normal file
81
docs/index.md
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
# About GraphQL
|
||||||
|
|
||||||
|
GraphQL is a modern way to build HTTP APIs consumed by web and mobile clients.
|
||||||
|
It is intended to be a replacement for REST and SOAP APIs (even for **existing applications**).
|
||||||
|
|
||||||
|
GraphQL itself is a [specification](https://github.com/facebook/graphql) designed by Facebook
|
||||||
|
engineers. Various implementations of this specification were written
|
||||||
|
[for different languages and environments](http://graphql.org/code/).
|
||||||
|
|
||||||
|
Great overview of GraphQL features and benefits is presented on [official website](http://graphql.org/).
|
||||||
|
All of them equally apply to this PHP implementation.
|
||||||
|
|
||||||
|
|
||||||
|
# About graphql-php
|
||||||
|
|
||||||
|
**graphql-php** is an implementation of GraphQL specification in PHP (5.4+, 7.0+).
|
||||||
|
It is based on [JavaScript implementation](https://github.com/graphql/graphql-js)
|
||||||
|
published by Facebook as a reference for others.
|
||||||
|
|
||||||
|
This library is a thin wrapper around your existing data layer and business logic.
|
||||||
|
It doesn't dictate how these layers are implemented or which storage engines
|
||||||
|
are used. Instead it provides tools for creating rich API for your existing app.
|
||||||
|
|
||||||
|
These tools include:
|
||||||
|
|
||||||
|
- Primitives to express your app as a Type System
|
||||||
|
- Tools for validation and introspection of this Type System
|
||||||
|
- Tools for parsing, validating and executing GraphQL queries against this Type System
|
||||||
|
- Rich error reporting
|
||||||
|
|
||||||
|
## Usage Example
|
||||||
|
```php
|
||||||
|
use GraphQL\GraphQL;
|
||||||
|
use GraphQL\Schema;
|
||||||
|
|
||||||
|
$query = '
|
||||||
|
{
|
||||||
|
hero {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
friends {
|
||||||
|
name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
';
|
||||||
|
|
||||||
|
$schema = new Schema([
|
||||||
|
// ...
|
||||||
|
// Type System definition for your app goes here
|
||||||
|
// ...
|
||||||
|
]);
|
||||||
|
|
||||||
|
$result = GraphQL::execute($schema, $query);
|
||||||
|
```
|
||||||
|
|
||||||
|
Result returned:
|
||||||
|
```php
|
||||||
|
[
|
||||||
|
'hero' => [
|
||||||
|
'id' => '2001',
|
||||||
|
'name' => 'R2-D2',
|
||||||
|
'friends' => [
|
||||||
|
['name' => 'Luke Skywalker'],
|
||||||
|
['name' => 'Han Solo'],
|
||||||
|
['name' => 'Leia Organa'],
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
Also check out full [Type System](https://github.com/webonyx/graphql-php/blob/master/tests/StarWarsSchema.php)
|
||||||
|
and [data source](https://github.com/webonyx/graphql-php/blob/master/tests/StarWarsData.php)
|
||||||
|
of this example.
|
||||||
|
|
||||||
|
## Current Status
|
||||||
|
Current version supports all features described by GraphQL specification
|
||||||
|
(including April 2016 add-ons) as well as some experimental features like
|
||||||
|
Schema Language parser.
|
||||||
|
|
||||||
|
Ready for real-world usage.
|
94
docs/overview.md
Normal file
94
docs/overview.md
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
# Concepts
|
||||||
|
GraphQL is data-centric. On the very top level it is built around three major concepts:
|
||||||
|
**Schema**, **Query** and **Mutation**.
|
||||||
|
|
||||||
|
You are expected to expresses your application as **Schema** (aka Type System) and expose it
|
||||||
|
with single HTTP endpoint. Application clients (e.g. web or mobile clients) send **Queries**
|
||||||
|
to this endpoint to request structured data and **Mutations** to perform changes.
|
||||||
|
|
||||||
|
## Queries
|
||||||
|
Queries are expressed in simple language that resembles JSON:
|
||||||
|
|
||||||
|
```graphql
|
||||||
|
{
|
||||||
|
hero {
|
||||||
|
name
|
||||||
|
friends {
|
||||||
|
name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
It was designed to mirror the structure of expected response:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"hero": {
|
||||||
|
"name": "R2-D2",
|
||||||
|
"friends": [
|
||||||
|
{"name": "Luke Skywalker"},
|
||||||
|
{"name": "Han Solo"},
|
||||||
|
{"name": "Leia Organa"}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
**graphql-php** runtime parses Queries, makes sure that they are valid for given Type System
|
||||||
|
and executes using data resolving tools provided by you as a part of integration.
|
||||||
|
|
||||||
|
## Mutations
|
||||||
|
Mutations use advanced features of the very same query language (like arguments and variables)
|
||||||
|
and have only semantic difference from Queries:
|
||||||
|
```graphql
|
||||||
|
mutation CreateReviewForEpisode($ep: Episode!, $review: ReviewInput!) {
|
||||||
|
createReview(episode: $ep, review: $review) {
|
||||||
|
stars
|
||||||
|
commentary
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
Variables `$ep` and `$review` are sent alongside with mutation. Full HTTP request might look like this:
|
||||||
|
```json
|
||||||
|
// POST /graphql-endpoint
|
||||||
|
// Content-Type: application/javascript
|
||||||
|
//
|
||||||
|
{
|
||||||
|
"query": "mutation CreateReviewForEpisode...",
|
||||||
|
"variables": {
|
||||||
|
"ep": "JEDI",
|
||||||
|
"review": {
|
||||||
|
"stars": 5,
|
||||||
|
"commentary": "This is a great movie!"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
As you see variables may include complex objects and they will be correctly validated by
|
||||||
|
**graphql-php** runtime.
|
||||||
|
|
||||||
|
Another nice feature of GraphQL mutations is that they also hold the query for data to be
|
||||||
|
returned after mutation. In our example mutation will return:
|
||||||
|
```
|
||||||
|
{
|
||||||
|
"createReview": {
|
||||||
|
"stars": 5,
|
||||||
|
"commentary": "This is a great movie!"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
# Type System
|
||||||
|
Type system is a heart of GraphQL integration. That's where **graphql-php** comes into play.
|
||||||
|
|
||||||
|
It provides following tools and primitives to describe your App as hierarchy of types:
|
||||||
|
|
||||||
|
* Primitives to work with **objects** and **interfaces**
|
||||||
|
* Primitives for defining **enumerations** and **unions**
|
||||||
|
* Primitives for defining custom **scalar types**
|
||||||
|
* Built-in scalar types: `ID`, `String`, `Int`, `Float`, `Boolean`
|
||||||
|
* Built-in type modifiers: `ListOf` and `NonNull`
|
||||||
|
|
||||||
|
# Further Reading
|
||||||
|
To get deeper understanding of GraphQL concepts - [read the docs on official website](http://graphql.org/learn/)
|
||||||
|
|
||||||
|
To get started with your own app - continue to next section ["Getting Started"](getting-started/)
|
1
docs/type-system.md
Normal file
1
docs/type-system.md
Normal file
@ -0,0 +1 @@
|
|||||||
|
TODOC
|
@ -1,5 +1,6 @@
|
|||||||
## Blog Example
|
## Blog Example
|
||||||
Simple yet full-featured example of GraphQL API. Models simple blog with Stories and Users.
|
Simple yet full-featured example of GraphQL API. Models blogging platform with Stories, Users
|
||||||
|
and hierarchical comments.
|
||||||
|
|
||||||
### Run locally
|
### Run locally
|
||||||
```
|
```
|
||||||
|
7
mkdocs.yml
Normal file
7
mkdocs.yml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
site_name: graphql-php
|
||||||
|
pages:
|
||||||
|
- About: index.md
|
||||||
|
- Overview: overview.md
|
||||||
|
- Getting Started: getting-started.md
|
||||||
|
- Type System: type-system.md
|
||||||
|
theme: readthedocs
|
Loading…
Reference in New Issue
Block a user