window.pipedriveLeadboosterConfig={です。 ベース:'leadbooster-chat.pipedrive.com'、 companyId:11580370, playbookUuid: '22236db1-6d50-40c4-b48f-8b11262155be', version: 2、 } ;(function () { var w = window もし (w.LeadBooster) {なら console.warn('LeadBooster already exists') } else { w.LeadBooster = { {. q: [], on: function (n, h) { this.q.push({ t: 'o', n: n, h: h }) }, trigger: 関数 (n) { { this.q.push({ t: 'o', n: n, h: h }) this.q.push({ t: 't', n: n }) }, } } })() RubyとGraphQLにおけるポリモーフィズム - The Codest
The Codest
  • 会社概要
  • サービス
    • ソフトウェア開発
      • フロントエンド開発
      • バックエンド開発
    • Staff Augmentation
      • フロントエンド開発者
      • バックエンド開発者
      • データエンジニア
      • クラウドエンジニア
      • QAエンジニア
      • その他
    • アドバイザリー
      • 監査&コンサルティング
  • 産業
    • フィンテック&バンキング
    • E-commerce
    • アドテック
    • ヘルステック
    • 製造業
    • 物流
    • 自動車
    • アイオーティー
  • 価値
    • CEO
    • CTO
    • デリバリー・マネージャー
  • チーム
  • Case Studies
  • ノウハウ
    • ブログ
    • ミートアップ
    • ウェビナー
    • リソース
採用情報 連絡先
  • 会社概要
  • サービス
    • ソフトウェア開発
      • フロントエンド開発
      • バックエンド開発
    • Staff Augmentation
      • フロントエンド開発者
      • バックエンド開発者
      • データエンジニア
      • クラウドエンジニア
      • QAエンジニア
      • その他
    • アドバイザリー
      • 監査&コンサルティング
  • 価値
    • CEO
    • CTO
    • デリバリー・マネージャー
  • チーム
  • Case Studies
  • ノウハウ
    • ブログ
    • ミートアップ
    • ウェビナー
    • リソース
採用情報 連絡先
戻る矢印 戻る
2022-01-13
ソフトウェア開発

RubyとGraphQLにおけるポリモーフィズム

ルカシュ・ブレジッチ

この記事では、GraphQLにおけるポリモーフィズムの使い方を紹介する。しかしその前に、ポリモーフィズムとGraphQLが何であるかを思い出しておく価値がある。

ポリモーフィズム

ポリモーフィズム の重要な構成要素である。 オブジェクト指向プログラミング.物事を単純化するために、これは異なるクラスのオブジェクトが同じインターフェースにアクセスできるという事実に基づいている。つまり Ruby開発者 が得られる。 多型 の3つである:

継承

継承 は、親クラスと子クラス(つまり親クラスを継承するクラス)を作成することにあります。子クラスは親クラスの機能を受け継ぎ、また機能を変更したり追加したりすることができます。

例

クラス ドキュメント
  attr_reader :名前
終了

クラス PDFDocument < ドキュメント
  def 拡張
    :pdf
  終了
終了

class ODTDocument < ドキュメント
  def 拡張
    :odt
  終了
終了

モジュール

モジュール ルビー には多くの使い方がある。そのひとつがミックスインだ(ミックスインについては 究極のブレークダウンルビー対Python).Rubyのミキシンは、他のプログラミング言語のインターフェイスと同じように使うことができます(例えば ジャワを含むオブジェクトに共通するメソッドを定義することができます。モジュールには読み取り専用のメソッドを含めるのがよい習慣です。つまり、このオブジェクトの状態を変更しないメソッドです。

例

課税モジュール
  デフタックス

     価格 * 0.23
  終了
終了

クラス Car
  課税対象を含む
 attr_reader :価格
終了

クラス Book
  課税対象を含む

 attr_reader :価格
終了

アヒルのタイピング

これは動的型付け言語の重要な特徴のひとつである。この名前は、「アヒルのように見え、アヒルのように泳ぎ、アヒルのように鳴くなら、それはおそらくアヒルである」という有名なテストに由来する。これは プログラマー は、与えられたオブジェクトがどのクラスに属しているかに関心を持つ必要はない。重要なのは、このオブジェクトに対して呼び出せるメソッドである。

上記の例で定義したクラスを使用する:

クラス 車
  attr_reader :価格

 def initialize(price)
    価格 = 価格
   終了
終了

クラス Book
  attr_reader :価格

 def initialize(price)
    価格 = 価格
  終了
終了

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

[車, 本].map(&:価格)

グラップル

GraphQL はAPI用の比較的新しいクエリー言語である。その利点は、非常にシンプルな構文を持っていること、さらに、各顧客が望むものを正確に得ることができ、それ以外は何も得ることができないため、クライアントが正確に得たいものを決めることができることである。

のサンプルクエリ GraphQL:

{
  すべてのユーザー
     ユーザー
        id
        ログイン
        電子メール

       }
     }
   }

回答例

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

現時点で知るべきことはこれだけだろう。では、本題に入ろう。

問題の提示

問題とその解決策を最もよく理解するために、例を作ってみよう。その例が独創的で、かつかなり現実的なものであればいい。私たち一人ひとりがいつか遭遇する可能性のあるものだ。動物はどうだろう?そうだ!いいアイデアだ!

rubyとgrapqlのポリモーフィズム - 動物

で書かれたバックエンドアプリケーションがあるとする。 Ruby on Rails.これは、上記のスキームを処理するためにすでに適応されている。また、すでに GraphQL を構成した。クライアントが以下の構造で問い合わせを行えるようにしたい:

{
 allZoos : {
    動物園{
      名前
      都市
      動物: {
        ...
      }
    }
  }
}

足りない情報を得るためには、3つの点の代わりに何を入れればいいのか。

実施

以下、目標を達成するために必要なステップを紹介しよう。

QueryTypeにクエリを追加する

まず、allZoosというクエリが何を意味するのかを定義する必要がある。そのためには、ファイルapp/graphql/types/query_type.rb とクエリーを定義する:

   モジュール Types
      class QueryType < Types::BaseObject
       フィールド :all_zoos, [Types::ZooType], null: false

       def all_zoos
          Zoo.all
       終了
    終了
 終了

クエリーはすでに定義されている。次は戻り値の型を定義する番だ。

タイプの定義

最初に必要なタイプはZooTypeです。ファイルで定義しましょう。 app/graphql/types/ zoo_type.rb:

モジュール Types
  class ZooType < Types::BaseObject
    field :name, String, null: false
    field :city, String, null: false
    field :animals, [Types::AnimalType], null: false
  終了
終了

次にAnimalType型を定義する:

モジュール Types
  class AnimalType < Types::BaseUnion
   指定可能な型 ElephantType, CatType, DogType

     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. AnimalTypeは タイプ::ベースユニオン.
  2. ある組合を構成しうるすべてのタイプをリストアップしなければならない。
    3.関数をオーバーライドする self.resolve_object(obj, ctx)、これは、与えられたオブジェクトの型を返さなければならない。

次のステップは、動物の種類を定義することである。しかし、いくつかのフィールドはすべての動物に共通であることがわかっている。それらをAnimalInterface型に含めよう:

モジュール Types
  モジュール AnimalInterface
    include Types::BaseInterface

    field :name, String, null: false
    field :age, 整数, null: false
  終了
終了

このインターフェイスがあれば、特定の動物のタイプを定義することができる:

モジュール Types
  class ElephantType < Types::BaseObject
    Types::AnimalInterface を実装

    フィールド :trunk_length, Float, null: false
  終了
終了

モジュール Types
  class CatType < Types::BaseObject
   Types::AnimalInterface を実装しています。

   フィールド :hair_type, String, null: false
  終了
終了

モジュール Types
  class DogType < Types::BaseObject
    Types::AnimalInterface を実装

     フィールド :breed, String, null: false
  終了
終了

そうだ!準備完了!最後の質問:クライアント側で行ったことをどのように使えばいいのでしょうか?

クエリーの構築

{
 allZoos : {
   動物園{
      名前
      都市
      動物: {
        名前

        ... on ElephantType { {...
          名前
          年齢
          体幹の長さ
        }

         ... on CatType { ...
          名前
          年齢
          ヘアタイプ
         }
         ... on DogType {
          名前
          年齢
          犬種
         }
       }

ここで追加の__typenameフィールドを使えば、与えられた要素の正確な型を返すことができる(例:CatType)。回答例はどのようになるでしょうか?

{
  "allZoos":[

   {
      "name":"Natura Artis Magistra"、
      "city":"アムステルダム"、
      "animals":[
        {
          "__typename":"エレファントタイプ"
          "name":"フランコ"、
          "age":28,
          「幹の長さ9.27
         },
         {
         "__typename":"DogType"
         "name":"Jack"、
         "age":9,
         犬種「ジャック・ラッセル・テリア
        },
      ]
    }
  ]
} 

分析

この方法の欠点は明らかである。クエリーでは、すべての動物がこれらのフィールドを持っていることがわかっているにもかかわらず、それぞれのタイプに名前と年齢を入力しなければならない。これは、コレクションにまったく異なるオブジェクトが含まれている場合には気にならない。しかし、この場合、動物はほとんどすべてのフィールドを共有している。どうにか改善できないだろうか?

もちろんだ!ファイルに最初の変更を加える app/graphql/types/zoo_type.rb:

モジュール Types
  class ZooType < Types::BaseObject
    field :name, String, null: false
    field :city, String, null: false
    field :animals, [Types::AnimalInterface], null: false
  終了
終了

私たちはもはや、これまで定義してきた組合を必要としない。次のように変更する。 タイプ::アニマルタイプ への Types::AnimalInterface.

次のステップは、以下の型を返す関数を追加することである。 タイプ ::動物インターフェース さらに、直接使われることのない型であるorphan_typesのリストも追加した:

モジュール Types
  モジュール AnimalInterface
    include Types::BaseInterface

   field :name, String, null: false
   field :age, 整数, null: false

   definition_methods do
      def resolve_type(obj, ctx)
        if obj.is_a?(Elephant)
          象型
        elsif obj.is_a?(Cat)
          CatType
        elsif obj.is_a?(Dog)
          DogType
        end
      end
    end
    orphan_types Types::ElephantType, Types::CatType, Types::DogType
  end
終了

このシンプルな手順のおかげで、クエリーはそれほど複雑な形をしていない:

{
  allZoos : {
   動物園{
      名前
      都市
      動物: {
        名前
        名前
        年齢

       ... on ElephantType { {...
          幹の長さ

       }
       ... on CatType { 毛の長さ } ... on CatType { 毛の長さ
          毛の長さ

       }
       ... on DogType { 犬種
          犬種

        }
      }
    }
  }
}

概要

GraphQL は本当に素晴らしいソリューションだ。まだ知らない人は試してみて。信じてほしい。これは、例えばREST APIに現れる問題を解決する上で素晴らしい仕事をしてくれる。上で示したように、 多型 は、そのための本当の障害ではない。私はそれに取り組むための2つの方法を提示した。
リマインダー

  • 共通のベースまたは共通のインターフェイスを持つオブジェクトのリストを操作する場合は、インターフェイスを使用します、
  • 異なる構造を持つオブジェクトのリストを操作する場合は、別のインターフェイスを使用する。

続きを読む

GraphQL Ruby。パフォーマンスについては?

レールおよびその他の輸送手段

TMUX、Vim、Fzf + RipgrepによるRails開発

関連記事

ソフトウェア開発

将来を見据えたウェブ・アプリケーションの構築:The Codestのエキスパート・チームによる洞察

The Codestが、最先端技術を駆使してスケーラブルでインタラクティブなウェブアプリケーションを作成し、あらゆるプラットフォームでシームレスなユーザー体験を提供することにどのように秀でているかをご覧ください。The Codestの専門知識がどのようにデジタルトランスフォーメーションとビジネス...

ザ・コデスト
ソフトウェア開発

ラトビアを拠点とするソフトウェア開発企業トップ10社

ラトビアのトップソフトウェア開発企業とその革新的なソリューションについて、最新記事でご紹介します。ラトビアの技術リーダーたちがあなたのビジネスをどのように向上させるかをご覧ください。

thecodest
エンタープライズ&スケールアップ・ソリューション

Javaソフトウェア開発の要点:アウトソーシングを成功させるためのガイド

outsourcingのJavaソフトウェア開発を成功させるために不可欠なこのガイドを読んで、The Codestで効率性を高め、専門知識にアクセスし、プロジェクトを成功に導きましょう。

thecodest
ソフトウェア開発

ポーランドにおけるアウトソーシングの究極ガイド

ポーランドのoutsourcingの急増は、経済、教育、技術の進歩がITの成長とビジネス・フレンドリーな環境を促進していることによる。

ザ・コデスト
エンタープライズ&スケールアップ・ソリューション

IT監査ツール&テクニック完全ガイド

IT監査は、安全かつ効率的で、コンプライアンスに準拠したシステムを保証します。その重要性については、記事全文をお読みください。

The Codest
ヤクブ・ヤクボヴィッチ CTO & 共同創設者

ナレッジベースを購読して、IT部門の専門知識を常に最新の状態に保ちましょう。

    会社概要

    The Codest - ポーランドに技術拠点を持つ国際的なソフトウェア開発会社。

    イギリス - 本社

    • オフィス 303B, 182-184 High Street North E6 2JA
      イギリス、ロンドン

    ポーランド - ローカル・テック・ハブ

    • ファブリチュナ・オフィスパーク、アレハ
      ポコジュ18、31-564クラクフ
    • ブレイン・エンバシー, コンストルクトースカ
      11, 02-673 Warsaw, Poland

      The Codest

    • ホーム
    • 会社概要
    • サービス
    • Case Studies
    • ノウハウ
    • 採用情報
    • 辞書

      サービス

    • アドバイザリー
    • ソフトウェア開発
    • バックエンド開発
    • フロントエンド開発
    • Staff Augmentation
    • バックエンド開発者
    • クラウドエンジニア
    • データエンジニア
    • その他
    • QAエンジニア

      リソース

    • 外部ソフトウェア開発パートナーとの協力に関する事実と神話
    • 米国から欧州へ:アメリカの新興企業がヨーロッパへの移転を決断する理由
    • テックオフショア開発ハブの比較:テックオフショア ヨーロッパ(ポーランド)、ASEAN(フィリピン)、ユーラシア(トルコ)
    • CTOとCIOの課題は?
    • The Codest
    • The Codest
    • The Codest
    • Privacy policy
    • ウェブサイト利用規約

    著作権 © 2025 by The Codest。無断複写・転載を禁じます。

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