window.pipedriveLeadboosterConfig = { base: 'leadbooster-chat.pipedrive.com', companyId: 11580370, playbookUuid: '22236db1-6d50-40c4-b48f-8b11262155be', version: 2, } ;(function () { var w = window if (w.LeadBooster) { console.warn('LeadBooster가 이미 존재합니다') } else { w.LeadBooster = { q: [], on: 함수 (n, h) { this.q.push({ t: 'o', n: n, h: h }) }, trigger: 함수 (n) { this.q.push({ t: 't', n: n }) }, } } })() 루비 및 그래프QL의 다형성 - The Codest
The Codest
  • 회사 소개
  • 서비스
    • 소프트웨어 개발
      • 프론트엔드 개발
      • 백엔드 개발
    • Staff Augmentation
      • 프론트엔드 개발자
      • 백엔드 개발자
      • 데이터 엔지니어
      • 클라우드 엔지니어
      • QA 엔지니어
      • 기타
    • IT 자문
      • 감사 및 컨설팅
  • 산업 분야
    • 핀테크 및 뱅킹
    • E-commerce
    • 애드테크
    • 헬스 테크
    • 제조
    • 물류
    • 자동차
    • IOT
  • 가치
    • CEO
    • CTO
    • 배달 관리자
  • 우리 팀
  • Case Studies
  • 방법 알아보기
    • 블로그
    • 모임
    • 웹 세미나
    • 리소스
채용 정보 연락하기
  • 회사 소개
  • 서비스
    • 소프트웨어 개발
      • 프론트엔드 개발
      • 백엔드 개발
    • Staff Augmentation
      • 프론트엔드 개발자
      • 백엔드 개발자
      • 데이터 엔지니어
      • 클라우드 엔지니어
      • QA 엔지니어
      • 기타
    • IT 자문
      • 감사 및 컨설팅
  • 가치
    • CEO
    • CTO
    • 배달 관리자
  • 우리 팀
  • Case Studies
  • 방법 알아보기
    • 블로그
    • 모임
    • 웹 세미나
    • 리소스
채용 정보 연락하기
뒤로 화살표 뒤로 가기
2022-01-13
소프트웨어 개발

루비 및 그래프QL의 다형성

루카스 브르제슈치

이 글에서는 GraphQL에서 다형성의 사용에 대해 설명하겠습니다. 그러나 시작하기 전에 다형성과 GraphQL이 무엇인지 상기할 필요가 있습니다.

다형성

다형성 의 핵심 구성 요소입니다. 객체 지향 프로그래밍. 간단히 설명하자면, 서로 다른 클래스의 객체가 동일한 인터페이스에 액세스할 수 있다는 사실에 기반하며, 이는 각 객체에서 동일한 기능을 기대할 수 있지만 반드시 동일한 방식으로 구현될 필요는 없다는 것을 의미합니다. In 루비 개발자 얻을 수 있습니다 다형성 세 가지 방법이 있습니다:

상속

상속 는 부모 클래스와 자식 클래스(즉, 부모 클래스에서 상속)를 생성하는 것으로 구성됩니다. 하위 클래스는 부모 클래스의 기능을 받으면서도 기능을 변경하고 추가할 수 있습니다.

예시:

Document 클래스
  attr_reader :이름
end

클래스 PDFDocument < 문서
  def 확장
    :pdf
  end
end

클래스 ODTDocument < 문서
  def 확장
    :odt
  end
end

모듈

모듈 Ruby 에는 다양한 용도가 있습니다. 그중 하나가 믹스인입니다(믹스인에 대해 자세히 알아보기 궁극의 분석: 루비 대 Python). Ruby의 믹스인은 다른 프로그래밍 언어의 인터페이스와 유사하게 사용할 수 있습니다(예 Java), 예를 들어 주어진 믹스인을 포함할 객체에 공통된 메서드를 정의할 수 있습니다. 모듈에는 읽기 전용 메서드를 포함하는 것이 좋으므로 이 객체의 상태를 수정하지 않는 메서드는 포함하지 않는 것이 좋습니다.

예시:

모듈 Taxable
  def tax

     가격 * 0.23
  end
end

클래스 자동차
  포함 과세 대상
 attr_reader :가격
end

클래스 Book
  포함 과세 대상

 attr_reader :가격
end

오리 타이핑

이것은 동적 유형 언어의 주요 특징 중 하나입니다. 오리처럼 보이고, 오리처럼 헤엄치고, 오리처럼 꽥꽥거리면 오리라는 유명한 테스트에서 유래한 이름입니다. 그리고 프로그래머 는 주어진 객체가 어느 클래스에 속하는지는 중요하지 않습니다. 중요한 것은 이 객체에서 호출할 수 있는 메서드입니다.

위의 예제에서 정의된 클래스를 사용합니다:

클래스 자동차
  attr_reader :가격

 def initialize(price)
    가격 = 가격
   end
end

Book 클래스
  attr_reader :가격

 def initialize(price)
    가격 = 가격
  end
end

car = Car.new(20.0)
book = Book.new(10.0)

[car, book].map(&:price

GrapQL

GraphQL 는 비교적 새로운 API용 쿼리 언어입니다. 이 언어의 장점은 구문이 매우 간단하다는 점과 각 고객이 원하는 것을 정확히 얻을 수 있기 때문에 고객이 원하는 것을 정확히 결정할 수 있다는 점입니다.

의 샘플 쿼리 GraphQL:

{
  모든 사용자 {
     사용자 {
        id
        로그인
        이메일

       }
     }
   }

샘플 응답:

{
  "allUsers": {
    "users": [
     {
        "id": 1,
        "login": "user1",
        "이메일": "[email protected]"
      },
      {
        "id": 2,
        "login": "user2",
        "이메일": "[email protected]"
      },
    ]
  }
}

현재로서는 이것이 우리가 알아야 할 전부일 것입니다. 그럼 본론으로 들어가 보겠습니다.

문제 제시

문제와 해결책을 가장 잘 이해하기 위해 예시를 만들어 보겠습니다. 이 예는 독창적이면서도 현실적인 것이면 좋을 것입니다. 우리 각자가 언젠가 마주칠 수 있는 상황이면 좋겠죠. 동물은 어떨까요? 좋아요! 좋은 생각입니다!

루비 및 GRAPQL 다형성 - 동물

백엔드 애플리케이션이 다음과 같이 작성되어 있다고 가정해 보겠습니다. Ruby on Rails. 이미 위의 체계를 처리하도록 조정되어 있습니다. 또한 이미 다음이 있다고 가정해 보겠습니다. GraphQL 를 구성했습니다. 클라이언트가 다음 구조 내에서 문의를 할 수 있도록 하려고 합니다:

{
 allZoos : {
    zoo: {
      name
      city
      animals: {
        ...
      }
    }
  }
}

누락된 정보를 얻으려면 세 개의 점 대신 무엇을 넣어야 하는지 나중에 알아보겠습니다.

구현

아래에서 목표를 달성하는 데 필요한 단계를 설명합니다.

쿼리 유형에 쿼리 추가하기

먼저, allZoos 쿼리가 정확히 무엇을 의미하는지 정의해야 합니다. 이를 위해 다음 파일을 방문해야 합니다.앱/그래프QL/유형/쿼리_유형.rb 를 클릭하고 쿼리를 정의합니다:

   모듈 유형
      QueryType 클래스 < Types::BaseObject
       field :all_zoos, [Types::ZooType], null: false

       def all_zoos
          Zoo.all
       end
    end
 end

쿼리는 이미 정의되어 있습니다. 이제 반환 유형을 정의할 차례입니다.

유형 정의

가장 먼저 필요한 유형은 ZooType입니다. 파일에서 정의해 보겠습니다. app/graphql/types/ zoo_type.rb:

모듈 유형
  ZooType 클래스 < Types::BaseObject
    필드 :이름, 문자열, 널: 거짓
    field :city, String, null: false
    field :animals, [Types::AnimalType], null: false
  end
end

이제 AnimalType 유형을 정의할 차례입니다:

모듈 유형
  AnimalType < Types::BaseUnion
   가능한_유형 코끼리형, 고양이형, 개형

     def self.resolve_type(obj, ctx)
       if obj.is_a?(Elephant)
          ElephantType
       elsif obj.is_a?(Cat)
         CatType
       elsif obj.is_a?(Dog)
        DogType
      end
    end
  end
end

에서 무엇을 볼 수 있습니까? 코드 위에?

  1. 동물 유형은 다음을 상속합니다. 유형::베이스유니온.
  2. 주어진 유니온을 구성할 수 있는 모든 유형을 나열해야 합니다.
    3. 함수 재정의 self.resolve_object(obj, ctx),는 지정된 객체의 유형을 반환해야 합니다.

다음 단계는 동물의 종류를 정의하는 것입니다. 하지만 일부 필드는 모든 동물에 공통으로 적용됩니다. 이를 AnimalInterface 유형에 포함시켜 보겠습니다:

모듈 유형
  동물 인터페이스 모듈
    포함 유형::베이스인터페이스

    field :name, 문자열, null: false
    field :age, Integer, null: false
  end
end

이 인터페이스를 통해 특정 동물의 유형을 정의할 수 있습니다:

모듈 유형
  엘리펀트 타입 < Types::BaseObject
    Types::AnimalInterface를 구현합니다.

    필드 :트렁크_길이, 플로트, 널: 거짓
  end
end

모듈 유형
  CatType < Types::BaseObject
   Types::AnimalInterface를 구현합니다.

   field :hair_type, String, null: false
  end
end

모듈 유형
  DogType 클래스 < Types::BaseObject
    Types::AnimalInterface를 구현합니다.

     필드 :품종, 문자열, 널: 거짓
  end
end

그거예요! 준비 완료! 마지막 질문: 클라이언트 측에서 우리가 만든 것을 어떻게 사용할 수 있을까요?

쿼리 작성

{
 allZoos : {
   zoo: {
      name
      city
      animals: {
        __유형명

        ... 엘리펀트 타입 {
          name
          age
          트렁크 길이
        }

         ... on CatType {
          name
          age
          hairType
         }
         ... on DogType {
          name
          age
          breed
         }
       }
     }
   }
 }

여기에 추가 __typename 필드를 사용하면 주어진 요소의 정확한 유형(예: CatType)을 반환할 수 있습니다. 샘플 답변은 어떤 모습일까요?

{
  "allZoos": [

   {
      "name": "나투라 아티스 매지스트라",
      "도시": "암스테르담",
      "동물": [
        {
          "__유형명": "ElephantType"
          "name": "프랑코",
          "age": 28,
          "trunkLength": 9.27
         },
         {
         "__typename": "DogType"
         "name": "Jack",
         "age": 9,
         "품종": "잭 러셀 테리어"
        },
      ]
    }
  ]
} 

분석

이 접근 방식의 한 가지 단점은 분명합니다. 모든 동물에 이러한 필드가 있다는 것을 알고 있지만 쿼리에서 각 유형에 이름과 나이를 입력해야 합니다. 컬렉션에 완전히 다른 개체가 포함되어 있을 때는 문제가 되지 않습니다. 그러나 이 경우에는 동물들이 거의 모든 필드를 공유합니다. 어떻게 하면 개선할 수 있을까요?

물론입니다! 파일에서 첫 번째 변경을 수행합니다. app/graphql/types/zoo_type.rb:

모듈 유형
  ZooType 클래스 < Types::BaseObject
    필드 :이름, 문자열, 널: 거짓
    field :city, String, null: false
    field :animals, [Types::AnimalInterface], null: false
  end
end

이전에 정의했던 유니온은 더 이상 필요하지 않습니다. 우리는 변화합니다. 유형::동물 유형 에 유형::동물 인터페이스.

다음 단계는 다음에서 유형을 반환하는 함수를 추가하는 것입니다. 유형 :: 동물 인터페이스 를 추가하고, 직접 사용되지 않는 유형인 orphan_유형 목록도 추가합니다:

모듈 유형
  동물 인터페이스 모듈
    포함 유형::베이스인터페이스

   field :name, 문자열, null: false
   field :age, 정수, null: false

   정의_방법 do
      def resolve_type(obj, ctx)
        if obj.is_a?(엘리펀트)
          ElephantType
        elsif obj.is_a?(Cat)
          CatType
        elsif obj.is_a?(Dog)
          DogType
        end
      end
    end
    orphan_types Types::ElephantType, Types::CatType, Types::DogType
  end
end

이 간단한 절차 덕분에 쿼리 형식이 덜 복잡해졌습니다:

{
  allZoos : {
   zoo: {
      name
      city
      animals: {
        __유형명
        이름
        age

       ... 엘리펀트 타입 {
          트렁크 길이

       }
       ... on CatType {
          hairType

       }
       ... on DogType {
          breed

        }
      }
    }
  }
}

요약

GraphQL 는 정말 훌륭한 솔루션입니다. 아직 모르신다면 한번 사용해 보세요. 그만한 가치가 있습니다. 예를 들어 REST API에서 나타나는 문제를 해결하는 데 매우 효과적입니다. 위에서 보여드렸듯이, 다형성 는 실제 장애물이 아닙니다. 이를 해결하기 위한 두 가지 방법을 제시했습니다.
알림:

  • 공통 기반 또는 공통 인터페이스를 가진 객체 목록에서 작업하는 경우 인터페이스를 사용하세요,
  • 구조가 다른 객체 목록에서 작업하는 경우 다른 인터페이스를 사용하세요 - 유니온을 사용하세요.

자세히 보기

GraphQL Ruby. 성능은 어떨까요?

철도 및 기타 운송 수단

TMUX, Vim, Fzf + Ripgrep을 사용한 레일 개발

관련 문서

소프트웨어 개발

미래 지향적인 웹 앱 구축: The Codest의 전문가 팀이 제공하는 인사이트

The Codest가 최첨단 기술로 확장 가능한 대화형 웹 애플리케이션을 제작하고 모든 플랫폼에서 원활한 사용자 경험을 제공하는 데 탁월한 성능을 발휘하는 방법을 알아보세요. Adobe의 전문성이 어떻게 디지털 혁신과 비즈니스를 촉진하는지 알아보세요...

최신
소프트웨어 개발

라트비아에 본사를 둔 10대 소프트웨어 개발 기업

최신 기사에서 라트비아 최고의 소프트웨어 개발 기업과 그들의 혁신적인 솔루션에 대해 알아보세요. 이러한 기술 리더들이 어떻게 귀사의 비즈니스를 향상시키는 데 도움을 줄 수 있는지 알아보세요.

thecodest
엔터프라이즈 및 스케일업 솔루션

Java 소프트웨어 개발 필수 사항: 성공적인 아웃소싱을 위한 가이드

The Codest로 효율성을 높이고 전문 지식을 활용하며 프로젝트 성공을 이끌 수 있는 성공적인 outsourcing Java 소프트웨어 개발에 대한 이 필수 가이드를 살펴보세요.

thecodest
소프트웨어 개발

폴란드 아웃소싱을 위한 최고의 가이드

폴란드에서 outsourcing가 급증한 것은 경제, 교육, 기술 발전으로 인한 IT 성장과 비즈니스 친화적인 환경이 조성된 덕분입니다.

더코데스트
엔터프라이즈 및 스케일업 솔루션

IT 감사 도구 및 기술에 대한 완벽한 가이드

IT 감사는 안전하고 효율적이며 규정을 준수하는 시스템을 보장합니다. 전체 기사를 읽고 그 중요성에 대해 자세히 알아보세요.

The Codest
야쿱 야쿠보비치 CTO & 공동 설립자

지식창고를 구독하고 IT 분야의 전문 지식을 최신 상태로 유지하세요.

    회사 소개

    The Codest - 폴란드에 기술 허브를 둔 국제 소프트웨어 개발 회사입니다.

    영국 - 본사

    • 사무실 303B, 182-184 하이 스트리트 노스 E6 2JA
      영국 런던

    폴란드 - 현지 기술 허브

    • 파브리츠나 오피스 파크, 알레야
      포코주 18, 31-564 크라쿠프
    • 뇌 대사관, 콘스트럭터스카
      11, 02-673 바르샤바, 폴란드

      The Codest

    • 홈
    • 회사 소개
    • 서비스
    • Case Studies
    • 방법 알아보기
    • 채용 정보
    • 사전

      서비스

    • IT 자문
    • 소프트웨어 개발
    • 백엔드 개발
    • 프론트엔드 개발
    • Staff Augmentation
    • 백엔드 개발자
    • 클라우드 엔지니어
    • 데이터 엔지니어
    • 기타
    • QA 엔지니어

      리소스

    • 외부 소프트웨어 개발 파트너와의 협력에 대한 사실과 오해
    • 미국에서 유럽으로: 미국 스타트업이 유럽으로 이전을 결정하는 이유
    • 테크 오프쇼어 개발 허브 비교: 테크 오프쇼어 유럽(폴란드), 아세안(필리핀), 유라시아(터키)
    • CTO와 CIO의 주요 과제는 무엇인가요?
    • The Codest
    • The Codest
    • The Codest
    • Privacy policy
    • 웹사이트 이용 약관

    저작권 © 2025 by The Codest. 모든 권리 보유.

    ko_KRKorean
    en_USEnglish de_DEGerman sv_SESwedish da_DKDanish nb_NONorwegian fiFinnish fr_FRFrench pl_PLPolish arArabic it_ITItalian jaJapanese es_ESSpanish nl_NLDutch etEstonian elGreek ko_KRKorean