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 on juba olemas') } else { w.LeadBooster = { q: [], on: function (n, h) { this.q.push({ t: 'o', n: n, h: h }) }, trigger: function (n) { this.q.push({ t: 't', n: n }) }, } } })() Polümorfism Ruby ja GraphQL - The Codest
The Codest
  • Meie kohta
  • Teenused
    • Tarkvaraarendus
      • Frontend arendus
      • Backend arendus
    • Staff Augmentation
      • Frontend arendajad
      • Backend arendajad
      • Andmeinsenerid
      • Pilveinsenerid
      • QA insenerid
      • Muud
    • See nõuandev
      • Audit ja nõustamine
  • Tööstusharud
    • Fintech & pangandus
    • E-commerce
    • Adtech
    • Healthtech
    • Tootmine
    • Logistika
    • Autotööstus
    • IOT
  • Väärtus
    • CEO
    • CTO
    • Tarnejuht
  • Meie meeskond
  • Case Studies
  • Tea kuidas
    • Blogi
    • Kohtumised
    • Veebiseminarid
    • Ressursid
Karjäärivõimalused Võtke ühendust
  • Meie kohta
  • Teenused
    • Tarkvaraarendus
      • Frontend arendus
      • Backend arendus
    • Staff Augmentation
      • Frontend arendajad
      • Backend arendajad
      • Andmeinsenerid
      • Pilveinsenerid
      • QA insenerid
      • Muud
    • See nõuandev
      • Audit ja nõustamine
  • Väärtus
    • CEO
    • CTO
    • Tarnejuht
  • Meie meeskond
  • Case Studies
  • Tea kuidas
    • Blogi
    • Kohtumised
    • Veebiseminarid
    • Ressursid
Karjäärivõimalused Võtke ühendust
Tagasi nool TAGASI
2022-01-13
Tarkvaraarendus

Polümorfism Ruby's ja GraphQLis

Lukasz Brzeszcz

Selles artiklis tutvustan polümorfismi kasutamist GraphQLis. Enne alustamist tasub aga meenutada, mis on polümorfism ja GraphQL.

Polümorfism

Polümorfism on üks põhikomponente objektorienteeritud programmeerimine. Lihtsustuseks põhineb see asjaolul, et erinevate klasside objektidel on juurdepääs samale liidesele, mis tähendab, et me võime igaühelt neist oodata sama funktsionaalsust, kuid mitte tingimata samamoodi rakendatuna. Veebilehel Ruby arendajad võib saada polümorfism kolmel viisil:

Pärimine

Pärimine seisneb vanema klassi ja lasteklasside loomises (st pärimine vanema klassist). Alamklassid saavad vanemklassi funktsionaalsuse ja võimaldavad ka funktsionaalsust muuta ja lisada.

Näide:

klass Dokument
  attr_reader :name
end

class PDFDocument < Document
  def extension
    :pdf
  end
end

class ODTDocument < Document
  def extension
    :odt
  end
end

Moodulid

Moodulid Ruby on palju kasutusvõimalusi. Üks neist on mixins (lugege mixins'idest lähemalt dokumendis Lõplik lagunemine: Ruby vs. Python). Ruby's saab mixins'e kasutada sarnaselt liidestega teistes programmeerimiskeeltes (nt. Java), näiteks saab neis defineerida meetodid, mis on ühised objektidele, mis sisaldavad antud mixin'i. Hea tava on lisada moodulitesse ainult lugemiseks mõeldud meetodeid, seega meetodeid, mis ei muuda selle objekti olekut.

Näide:

moodul Maksustatav
  def tax

     hind * 0.23
  end
end

klass Auto
  include Taxable
 attr_reader :price
end

class Book
  include Taxable

 attr_reader :price
end

Pardi kirjutamine

See on üks dünaamiliselt tüpiseeritud keelte peamisi omadusi. Nimi tuleneb kuulsast testist: kui see näeb välja nagu part, ujub nagu part ja vikiseb nagu part, siis on see tõenäoliselt part. Veebileht programmeerija ei pea olema huvitatud sellest, millisesse klassi antud objekt kuulub. Olulised on meetodid, mida saab selle objektile kutsuda.

Kasutades ülaltoodud näites määratletud klassid:

klass Auto
  attr_reader :price

 def initialize(price)
    @hind = hind
   end
end

class Book
  attr_reader :price

 def initialize(price)
    @hind = hind
  end
end

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

[auto, raamat].map(&:price

GrapQL

GraphQL on suhteliselt uus APIde päringukeel. Selle eeliste hulka kuulub asjaolu, et selle süntaks on väga lihtne ja lisaks sellele otsustab klient ise, mida ta täpselt tahab saada, sest iga klient saab täpselt seda, mida ta tahab, ja mitte midagi muud.

Näidise päring GraphQL:

{
  allUsers {
     users {
        id
        login
        email

       }
     }
   }

Näidisvastus:

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

See on ilmselt kõik, mida meil on hetkel vaja teada. Niisiis, lähme asja juurde.

Probleemi esitamine

Probleemi ja selle lahenduse paremaks mõistmiseks loome näite. Oleks hea, kui näide oleks nii originaalne kui ka üsna maalähedane. Selline, millega igaüks meist võib kunagi kokku puutuda. Kuidas oleks näiteks... loomad? Jah! Suurepärane idee!

ruby ja grapql polümorfism - loomad

Oletame, et meil on backend-rakendus, mis on kirjutatud keeles Ruby on Rails. See on juba kohandatud eespool nimetatud skeemi käsitlemiseks. Oletame ka, et meil on juba GraphQL konfigureeritud. Me tahame võimaldada kliendil teha päringu järgmise struktuuri raames:

{
 allZoos : {
    zoo: {
      name
      linn
      loomad: {
        ...
      }
    }
  }
}

Mida tuleks panna kolme punkti asemele, et saada puuduolevat teavet - saame teada hiljem.

Rakendamine

Järgnevalt tutvustan eesmärgi saavutamiseks vajalikke samme.

Päringu lisamine QueryType'ile

Kõigepealt tuleb määratleda, mida täpselt tähendab päring allZoos. Selleks peame külastama failiapp/graphql/types/query_type.rb ja määratleda päring:

   moodul Tüübid
      class QueryType < Types::BaseObject
       väli :all_zoos, [Types::ZooType], null: false

       def all_zoos
          Zoo.all
       end
    end
 end

Päring on juba määratletud. Nüüd on aeg määratleda tagastustüübid.

Tüüpide määratlus

Esimene nõutav tüüp on ZooType. Määratleme selle failis app/graphql/types/ zoo_type.rb:

moodul Tüübid
  class ZooType < Types::BaseObject
    väli :name, String, null: false
    väli :city, String, null: false
    väli :animals, [Types::AnimalType], null: false
  end
end

Nüüd on aeg defineerida tüüp AnimalType:

moodul Tüübid
  class AnimalType < Types::BaseUnion
   possible_types 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

Mida me näeme kood eespool?

  1. AnimalType pärib Tüübid::BaseUnion.
  2. Me peame loetlema kõik tüübid, mis võivad moodustada konkreetse liidu.
    3.Me ületame funktsiooni self.resolve_object(obj, ctx),mis peab tagastama antud objekti tüübi.

Järgmine samm on loomade liikide määratlemine. Me teame siiski, et mõned väljad on kõigile loomadele ühised. Lisame need tüüpi AnimalInterface:

moodul Tüübid
  moodul AnimalInterface
    include Types::BaseInterface

    väli :name, String, null: false
    väli :age, täisarv, null: false
  end
end

Selle liidese olemasolul saame jätkata konkreetsete loomade tüüpide määratlemist:

moodul Tüübid
  class ElephantType < Types::BaseObject
    implementeerib Types::AnimalInterface

    väli :trunk_length, Float, null: false
  end
end

moodul Tüübid
  class CatType < Types::BaseObject
   implementeerib Types::AnimalInterface

   väli :hair_type, String, null: false
  end
end

moodul Tüübid
  class DogType < Types::BaseObject
    implementeerib Types::AnimalInterface

     väli :breed, String, null: false
  end
end

See on kõik! Valmis! Üks viimane küsimus: kuidas me saame kasutada seda, mida me oleme teinud kliendi poolelt?

Päringu koostamine

{
 allZoos : {
   zoo: {
      name
      linn
      loomad: {
        __typename

        ... on ElephantType {
          name
          age
          trunkLength
        }

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

Me võime siin kasutada täiendavat __typename-välja, mis tagastab antud elemendi täpse tüübi (nt CatType). Milline näeb välja näidisvastus?

{
  "allZoos": [

   {
      "name": "Natura Artis Magistra",
      "city": "Amsterdam",
      "animals": [
        {
          "__typename": "ElephantType"
          "name": "Franco",
          "age": 28,
          "trunkLength": 9.27
         },
         {
         "__typename": "DogType"
         "name": "Jack",
         "age": 9,
         "tõug": "Jack Russell Terrier"
        },
      ]
    }
  ]
} 

Analüüs

Selle lähenemisviisi üks puudus on ilmne. Päringus peame iga tüübi puhul sisestama nime ja vanuse, kuigi me teame, et need väljad on kõigil loomadel olemas. See ei ole häiriv, kui kollektsioon sisaldab täiesti erinevaid objekte. Antud juhul on aga loomadel peaaegu kõik väljad ühised. Kas seda saab kuidagi parandada?

Loomulikult! Teeme failis esimese muudatuse app/graphql/types/zoo_type.rb:

moodul Tüübid
  class ZooType < Types::BaseObject
    väli :name, String, null: false
    väli :city, String, null: false
    väli :animals, [Types::AnimalInterface], null: false
  end
end

Me ei vaja enam seda liitu, mida me varem määratlesime. Me muudame Tüübid::AnimalType aadressile Tüübid::AnimalInterface.

Järgmine samm on lisada funktsioon, mis tagastab tüübist Tüübid :: AnimalInterface ja lisage ka nimekiri orphan_types, st tüübid, mida ei kasutata kunagi otseselt:

moodul Tüübid
  moodul AnimalInterface
    include Types::BaseInterface

   väli :name, String, null: false
   väli :age, täisarv, null: false

   definition_methods do
      def 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
    orphan_types Types::ElephantType, Types::CatType, Types::DogType
  end
end

Tänu sellele lihtsale protseduurile on päring vähem keerulises vormis:

{
  allZoos : {
   zoo: {
      name
      linn
      loomad: {
        __typename
        name
        age

       ... on ElephantType {
          trunkLength

       }
       ... on CatType {
          hairType

       }
       ... on DogType {
          breed

        }
      }
    }
  }
}

Kokkuvõte

GraphQL on tõesti suurepärane lahendus. Kui te seda veel ei tea, proovige seda. Uskuge mind, see on seda väärt. See teeb suurepärast tööd näiteks REST API-des ilmnevate probleemide lahendamisel. Nagu ma eespool näitasin, polümorfism ei ole selle jaoks tõeline takistus. Esitasin kaks meetodit selle lahendamiseks.
Meeldetuletus:

  • Kui töötate ühise baasiga või ühise liidesega objektide loeteluga - kasutage liideseid,
  • Kui te töötate erineva struktuuriga objektide loendiga, kasutage teistsugust liidest - kasutage liitu union

Loe edasi

GraphQL Ruby. Kuidas on tulemuslikkus?

Rööpad ja muud transpordivahendid

Railsi arendamine TMUX, Vim, Fzf + Ripgrep abil

Seotud artiklid

Tarkvaraarendus

Tulevikukindlate veebirakenduste loomine: The Codest ekspertide meeskonna ülevaade

Avastage, kuidas The Codest paistab skaleeritavate, interaktiivsete veebirakenduste loomisel silma tipptehnoloogiatega, mis pakuvad sujuvat kasutajakogemust kõigil platvormidel. Saate teada, kuidas meie eksperditeadmised aitavad kaasa digitaalsele ümberkujundamisele ja äritegevusele...

THECODEST
Tarkvaraarendus

Top 10 Lätis asuvat tarkvaraarendusettevõtet

Tutvu Läti parimate tarkvaraarendusettevõtete ja nende innovaatiliste lahendustega meie viimases artiklis. Avastage, kuidas need tehnoloogiajuhid saavad aidata teie äri edendada.

thecodest
Enterprise & Scaleups lahendused

Java tarkvaraarenduse põhitõed: A Guide to Outsourcing Successfully

Tutvuge selle olulise juhendiga, kuidas edukalt outsourcing Java tarkvara arendada, et suurendada tõhusust, pääseda ligi eksperditeadmistele ja edendada projekti edu The Codest abil.

thecodest
Tarkvaraarendus

Ülim juhend Poola allhanke kohta

outsourcing kasv Poolas on tingitud majanduslikust, hariduslikust ja tehnoloogilisest arengust, mis soodustab IT kasvu ja ettevõtlussõbralikku kliimat.

TheCodest
Enterprise & Scaleups lahendused

Täielik juhend IT-auditi vahendite ja tehnikate kohta

IT-auditid tagavad turvalised, tõhusad ja nõuetele vastavad süsteemid. Lisateavet nende tähtsuse kohta leiate kogu artiklist.

The Codest
Jakub Jakubowicz CTO & kaasasutajad

Tellige meie teadmistebaas ja jääge kursis IT-sektori eksperditeadmistega.

    Meie kohta

    The Codest - rahvusvaheline tarkvaraarendusettevõte, mille tehnoloogiakeskused asuvad Poolas.

    Ühendkuningriik - peakorter

    • Büroo 303B, 182-184 High Street North E6 2JA
      London, Inglismaa

    Poola - kohalikud tehnoloogiakeskused

    • Fabryczna büroopark, Aleja
      Pokoju 18, 31-564 Kraków
    • Brain Embassy, Konstruktorska
      11, 02-673 Varssavi, Poola

      The Codest

    • Kodu
    • Meie kohta
    • Teenused
    • Case Studies
    • Tea kuidas
    • Karjäärivõimalused
    • Sõnastik

      Teenused

    • See nõuandev
    • Tarkvaraarendus
    • Backend arendus
    • Frontend arendus
    • Staff Augmentation
    • Backend arendajad
    • Pilveinsenerid
    • Andmeinsenerid
    • Muud
    • QA insenerid

      Ressursid

    • Faktid ja müüdid koostööst välise tarkvaraarenduspartneriga
    • USAst Euroopasse: Miks otsustavad Ameerika idufirmad Euroopasse ümber asuda?
    • Tech Offshore arenduskeskuste võrdlus: Euroopa (Poola), ASEAN (Filipiinid), Euraasia (Türgi).
    • Millised on CTO ja CIOde peamised väljakutsed?
    • The Codest
    • The Codest
    • The Codest
    • Privacy policy
    • Website terms of use

    Copyright © 2025 by The Codest. Kõik õigused kaitstud.

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