架构SOLID
SOLID
Gato GraphQL 在软件架构中采用了 SOLID 方法,通过提供不同的实体来处理不同的职责,从而使代码具有可维护性、可扩展性和可理解性。
以下是插件已提供的用户实体示例。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;
}
}类型解析器不会直接从数据库加载对象,而是将此任务委托给 TypeDataLoader 对象(在上面的示例中,来自类 UserTypeDataLoader)。
向 User 类型添加 username、email 和 url 字段是通过具有此代码的 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:用于声明字段参数(包括其名称、描述、类型以及是否为必填项)isSchemaFieldResponseNonNullable:用于指示字段是否为 non-nullablegetImplementedInterfaceClasses:用于为字段实现的接口定义解析器resolveFieldTypeResolverClass:用于在字段为连接时定义类型解析器resolveFieldMutationResolverClass:用于在字段执行 mutations 时定义解析器
与通过单个函数或配置数组实现所有功能相比,此代码更具可读性,从而使解析器的实现和维护更加便捷。