SOLID
Gato GraphQL ใช้แนวทาง SOLID สำหรับสถาปัตยกรรมซอฟต์แวร์ โดยจัดเตรียม entity ที่แตกต่างกันเพื่อรับผิดชอบในแต่ละด้าน เพื่อให้โค้ดสามารถบำรุงรักษา ขยาย และทำความเข้าใจได้ง่าย
นี่คือตัวอย่างที่ plugin จัดเตรียม user entity ไว้แล้ว ประเภท User ถูกจัดเตรียมผ่านโค้ดนี้:
class UserTypeResolver extends AbstractTypeResolver
{
public function getTypeName(): string
{
return 'User';
}
public function getSchemaTypeDescription(): ?string
{
return $this->translationAPI->__('Representation of a user', "users");
}
public function getID(object $user)
{
return $this->usersAPI->getUserId($user);
}
public function getTypeDataLoaderClass(): string
{
return UserTypeDataLoader::class;
}
}type resolver ไม่ได้โหลดออบเจ็กต์จากฐานข้อมูลโดยตรง แต่จะมอบหมายงานนี้ให้กับออบเจ็กต์ TypeDataLoader แทน (ในตัวอย่างข้างต้น มาจากคลาส UserTypeDataLoader)
การเพิ่มฟิลด์ username, email และ url ให้กับประเภท User ทำได้ผ่านออบเจ็กต์ FieldResolver ด้วยโค้ดนี้:
class UserFieldResolver extends AbstractDBDataFieldResolver
{
public static function getClassesToAttachTo(): array
{
return [
UserTypeResolver::class,
];
}
public static function getFieldNamesToResolve(): array
{
return [
'username',
'email',
'url',
];
}
public function getSchemaFieldDescription(
TypeResolverInterface $typeResolver,
string $fieldName
): ?string {
$descriptions = [
'username' => $this->translationAPI->__("User's username handle", "users"),
'email' => $this->translationAPI->__("User's email", "users"),
'url' => $this->translationAPI->__("URL of the user's profile in the website", "users"),
];
return $descriptions[$fieldName];
}
public function getSchemaFieldType(
TypeResolverInterface $typeResolver,
string $fieldName
): ?string {
$types = [
'username' => SchemaDefinition::TYPE_STRING,
'email' => SchemaDefinition::TYPE_EMAIL,
'url' => SchemaDefinition::TYPE_URL,
];
return $types[$fieldName];
}
public function resolveValue(
TypeResolverInterface $typeResolver,
object $user,
string $fieldName,
array $fieldArgs = []
) {
switch ($fieldName) {
case 'username':
return $this->usersAPI->getUserLogin($user);
case 'email':
return $this->usersAPI->getUserEmail($user);
case 'url':
return $this->usersAPI->getUserURL($user);
}
return null;
}
}จะเห็นได้ว่าการนิยามฟิลด์สำหรับ GraphQL schema และการแก้ไขค่าของมัน ถูกแบ่งออกเป็นหลายฟังก์ชัน:
getSchemaFieldDescriptiongetSchemaFieldTyperesolveValue
ฟังก์ชันอื่น ๆ ได้แก่:
getSchemaFieldArgs: เพื่อประกาศ argument ของฟิลด์ (รวมถึงชื่อ คำอธิบาย ประเภท และว่าจำเป็นต้องระบุหรือไม่)isSchemaFieldResponseNonNullable: เพื่อระบุว่าฟิลด์เป็น non-nullable หรือไม่getImplementedInterfaceClasses: เพื่อนิยาม resolver สำหรับอินเทอร์เฟซที่ฟิลด์นำไปใช้งานresolveFieldTypeResolverClass: เพื่อนิยาม type resolver เมื่อฟิลด์เป็น connectionresolveFieldMutationResolverClass: เพื่อนิยาม resolver เมื่อฟิลด์ดำเนินการmutations
โค้ดนี้อ่านง่ายกว่าการรวมฟังก์ชันทั้งหมดไว้ในฟังก์ชันเดียวหรือใช้ configuration array จึงทำให้การนำ resolver ไปใช้และบำรุงรักษาทำได้ง่ายขึ้น