아키텍처
아키텍처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 스키마의 필드 정의와 그 해결은 여러 함수로 분리되었습니다:

  • getSchemaFieldDescription
  • getSchemaFieldType
  • resolveValue

기타 함수에는 다음이 포함됩니다:

이 코드는 모든 기능을 단일 함수나 설정 배열로 구현하는 경우보다 가독성이 높아, 리졸버를 구현하고 유지 관리하기 더 쉽습니다.