Skip to content

Commit 714aa84

Browse files
committed
Merge branch 'source' of https://github.com/graphql/graphql.github.io into source
2 parents 5d4b666 + 2252ef5 commit 714aa84

File tree

1 file changed

+120
-0
lines changed

1 file changed

+120
-0
lines changed
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
---
2+
name: GraphQL by PoP
3+
description: CMS-agnostic GraphQL server in PHP. It follows the code-first approach, generating the schema dynamically
4+
url: https://graphql-by-pop.com
5+
github: leoloso/PoP
6+
---
7+
8+
GraphQL by PoP follows the [code-first approach](https://graphql-by-pop.com/docs/architecture/code-first.html) to generate the schema (it can be customized for different clients/applications). Fields are dynamically "subscribed" to types, and may or may not be added to the schema depending on the context.
9+
10+
This is how a `User` type is satisfied:
11+
12+
```php
13+
class UserTypeResolver extends AbstractTypeResolver
14+
{
15+
public function getTypeName(): string
16+
{
17+
return 'User';
18+
}
19+
20+
public function getSchemaTypeDescription(): ?string
21+
{
22+
$translationAPI = TranslationAPIFacade::getInstance();
23+
return $translationAPI->__('Representation of a user', 'users');
24+
}
25+
26+
public function getID(object $user)
27+
{
28+
return $user->ID;
29+
}
30+
31+
public function getTypeDataLoaderClass(): string
32+
{
33+
return UserTypeDataLoader::class;
34+
}
35+
}
36+
```
37+
38+
Please notice how the `TypeResolver` does not indicate which are its fields. It also does not load the objects from the database, but instead delegates this task to a `TypeDataLoader`.
39+
40+
Adding fields to the type is done via a `FieldResolver`:
41+
42+
```php
43+
class UserFieldResolver extends AbstractDBDataFieldResolver
44+
{
45+
public static function getClassesToAttachTo(): array
46+
{
47+
return [
48+
UserTypeResolver::class,
49+
];
50+
}
51+
52+
public static function getFieldNamesToResolve(): array
53+
{
54+
return [
55+
'username',
56+
'email',
57+
'url',
58+
];
59+
}
60+
61+
public function getSchemaFieldDescription(
62+
TypeResolverInterface $typeResolver,
63+
string $fieldName
64+
): ?string {
65+
$translationAPI = TranslationAPIFacade::getInstance();
66+
$descriptions = [
67+
'username' => $translationAPI->__("User's username handle", "users"),
68+
'email' => $translationAPI->__("User's email", "users"),
69+
'url' => $translationAPI->__("URL of the user's profile in the website", "users"),
70+
];
71+
return $descriptions[$fieldName];
72+
}
73+
74+
public function getSchemaFieldType(
75+
TypeResolverInterface $typeResolver,
76+
string $fieldName
77+
): ?string {
78+
$types = [
79+
'username' => SchemaDefinition::TYPE_STRING,
80+
'email' => SchemaDefinition::TYPE_EMAIL,
81+
'url' => SchemaDefinition::TYPE_URL,
82+
];
83+
return $types[$fieldName];
84+
}
85+
86+
public function resolveValue(
87+
TypeResolverInterface $typeResolver,
88+
object $user,
89+
string $fieldName,
90+
array $fieldArgs = []
91+
) {
92+
switch ($fieldName) {
93+
case 'username':
94+
return $user->user_login;
95+
96+
case 'email':
97+
return $user->user_email;
98+
99+
case 'url':
100+
$userService = UserServiceFacade::getInstance();
101+
return $userService->getUserProfileURL($user->ID);
102+
}
103+
104+
return null;
105+
}
106+
}
107+
```
108+
109+
The definition of a field for the GraphQL schema, and its resolution, is split into a multitude of functions from the `FieldResolver`:
110+
111+
- `getSchemaFieldDescription`
112+
- `getSchemaFieldType`
113+
- `resolveValue`
114+
- `getSchemaFieldArgs`
115+
- `isSchemaFieldResponseNonNullable`
116+
- `getImplementedInterfaceClasses`
117+
- `resolveFieldTypeResolverClass`
118+
- `resolveFieldMutationResolverClass`
119+
120+
This code is more legible than if all functionality is satisfied through a single function, or through a configuration array, making it easier to implement and maintain the resolvers.

0 commit comments

Comments
 (0)