Skip to content

Commit ca77f56

Browse files
Add examples/05-using-typeConfigDecorator-with-SDL (#1702)
1 parent afc1069 commit ca77f56

File tree

9 files changed

+158
-0
lines changed

9 files changed

+158
-0
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ You can find and compare releases at the [GitHub release page](https://github.co
99

1010
## Unreleased
1111

12+
### Added
13+
- Add **examples/05-using-typeConfigDecorator-with-SDL** to provide a solid example about resolving
14+
fields on using [SDL](https://webonyx.github.io/graphql-php/schema-definition-language/) instead of [Object Types](https://webonyx.github.io/graphql-php/type-definitions/object-types/).
15+
1216
## v15.20.0
1317

1418
### Added

docs/schema-definition-language.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ $contents = file_get_contents('schema.graphql');
5353
$schema = BuildSchema::build($contents, $typeConfigDecorator);
5454
```
5555

56+
You can learn more about using `$typeConfigDecorator` in [examples/05-using-typeConfigDecorator-with-SDL](../examples/05-using-typeConfigDecorator-with-SDL/)
57+
5658
## Performance considerations
5759

5860
Method **BuildSchema::build()** produces a [lazy schema](schema-definition.md#lazy-loading-of-types) automatically,
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Using typeConfigDecoration with SDL
2+
3+
This example is intended to show you the boilerplate that you would need to resolve object types in a query using the SDL instead of defining the schema using the Object Types.
4+
5+
**Code Context:** The business logic is from [Apollo graphql course. ](https://www.apollographql.com/tutorials/lift-off-part2/03-apollo-restdatasource) Full source code is also available in the accompanying repo for this course .
6+
7+
**Further explanation** : There is [an accompanying issue](https://github.com/webonyx/graphql-php/issues/1699) where I explained some of the boilerplate code .
8+
9+
## How to follow along ?
10+
1. Navigate to `examples/05-using-typeConfigDecorator-with-SDL` using the command line
11+
2. Run `composer install`
12+
3. Run `php -S localhost:8080 graphql.php`
13+
4. Use your favorite API client and make a request to `localhost:8080` . Provide the following as the request body :
14+
15+
```graphql
16+
{
17+
tracksForHome {
18+
title
19+
thumbnail
20+
author {
21+
id
22+
name
23+
}
24+
}
25+
}
26+
```
27+
28+
5. You can also use `curl` :
29+
```
30+
curl --data '{"query": "{ tracksForHome { title thumbnail author { id name } } }"}' --header "Content-Type: application/json" http://localhost:8080
31+
```
32+
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
namespace App\Models;
4+
5+
use Core\Model;
6+
7+
class Author extends Model {
8+
public static function find(int $id): array {
9+
return static::get("author/$id");
10+
}
11+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
namespace App\Models;
4+
5+
use Core\Model;
6+
7+
class Track extends Model {
8+
public static function all(): array {
9+
return static::get('tracks');
10+
}
11+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"autoload": {
3+
"psr-4": {
4+
"App\\": "app/",
5+
"Core\\": "core/"
6+
}
7+
},
8+
"require": {
9+
"webonyx/graphql-php": "^15.20"
10+
}
11+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
namespace Core;
3+
4+
use Exception;
5+
6+
class Model {
7+
protected static $basePath = "https://odyssey-lift-off-rest-api.herokuapp.com/";
8+
protected static function get(string $endpoint): array {
9+
$url = static::$basePath . $endpoint;
10+
11+
$res = file_get_contents($url);
12+
13+
if(!$res) {
14+
throw new Exception("Failed to fetch data from url: $url");
15+
}
16+
return json_decode($res, true);
17+
}
18+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
3+
require __DIR__ . '/vendor/autoload.php';
4+
5+
use App\Models\Track;
6+
use App\Models\Author;
7+
use GraphQL\GraphQL;
8+
use GraphQL\Utils\BuildSchema;
9+
10+
ini_set('display_errors', 1);
11+
12+
$typeConfigDecorator = function($typeConfig) {
13+
/*
14+
The hypothetical shape of $typeConfig in iterations :
15+
16+
[
17+
// Each iteration, the name property gets the name of a type from our schema like : Query, Track and Author
18+
'name': "Query",
19+
'fields': fn() => {}
20+
]
21+
*/
22+
switch($typeConfig['name']) {
23+
case "Query":
24+
$typeConfig['fields'] = function() use ($typeConfig) {
25+
$fields = $typeConfig['fields']();
26+
$fields['tracksForHome']['resolve'] = fn() => Track::all();
27+
return $fields;
28+
};
29+
break;
30+
case "Track":
31+
$typeConfig['fields'] = function() use ($typeConfig) {
32+
$fields = $typeConfig['fields']();
33+
$fields['author']['resolve'] = fn($track) => Author::find($track['authorId']);
34+
return $fields;
35+
};
36+
break;
37+
}
38+
return $typeConfig;
39+
};
40+
$contents = file_get_contents(__DIR__ . '/schema.graphql');
41+
$schema = BuildSchema::build($contents, $typeConfigDecorator);
42+
43+
$requestBody = file_get_contents('php://input');
44+
$parsedBody = json_decode($requestBody, true, 10);
45+
$queryString = $parsedBody['query'];
46+
47+
$result = GraphQL::executeQuery($schema, $queryString);
48+
49+
header('Content-Type: application/json');
50+
echo json_encode($result);
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
type Query {
2+
tracksForHome: [Track]
3+
4+
}
5+
6+
type Track {
7+
id: ID!
8+
title: String
9+
thumbnail: String
10+
length: Int
11+
modulesCount: Int
12+
author: Author
13+
}
14+
15+
type Author {
16+
id: ID!
17+
name: String
18+
photo: String
19+
}

0 commit comments

Comments
 (0)