(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); })(window,document,'script','dataLayer','GTM-5LHNRP9'); Margbreytileiki í Ruby og GraphQL - The Codest
The Codest
  • Um okkur
  • Þjónusta
    • Hugbúnaðarþróun
      • Framhliðþróun
      • Bakendaþróun
    • Staff Augmentation
      • Framhliðaráþrófarar
      • Bakhliðaráþróunaraðilar
      • Gagnaverkfræðingar
      • Skýjaverkfræðingar
      • Gæðatryggingartæknimenn
      • Annað
    • Það er ráðgjafi
      • Endurskoðun og ráðgjöf
  • Iðnaðargreinar
    • Fjártæknifyrirtæki og bankastarfsemi
    • E-commerce
    • Adtech
    • Heilbrigðistækni
    • Framleiðsla
    • Flutningar
    • Bifreiða
    • Internet hlutanna
  • Gildi fyrir
    • CEO
    • CTO
    • Afhendingarstjóri
  • Teymið okkar
  • Case Studies
  • Vitið hvernig
    • Blogg
    • Fundir
    • Vefnámskeið
    • Auðlindir
Starfsferilmöguleikar Hafðu samband
  • Um okkur
  • Þjónusta
    • Hugbúnaðarþróun
      • Framhliðþróun
      • Bakendaþróun
    • Staff Augmentation
      • Framhliðaráþrófarar
      • Bakhliðaráþróunaraðilar
      • Gagnaverkfræðingar
      • Skýjaverkfræðingar
      • Gæðatryggingartæknimenn
      • Annað
    • Það er ráðgjafi
      • Endurskoðun og ráðgjöf
  • Gildi fyrir
    • CEO
    • CTO
    • Afhendingarstjóri
  • Teymið okkar
  • Case Studies
  • Vitið hvernig
    • Blogg
    • Fundir
    • Vefnámskeið
    • Auðlindir
Starfsferilmöguleikar Hafðu samband
Aftur ör Farðu aftur
2022-01-13
Hugbúnaðarþróun

Polymorphism í Ruby og GraphQL

Lukasz Brzeszcz

Í þessari grein mun ég kynna notkun margforms í GraphQL. Áður en ég byrja er þó vert að rifja upp hvað margform og GraphQL eru.

Hér er tómt.

Mörgformun

Mörgformun er lykilþáttur í hlutbundin forritun. Til að einfalda hlutina er þetta byggt á þeirri staðreynd að hlutir úr mismunandi flokkum hafa aðgang að sama viðmóti, sem þýðir að við getum búist við sömu virkni frá hverjum þeirra, en ekki endilega að hún sé innleidd á sama hátt. Í Rúbín forritarar geta fengið fjölbreytileiki á þrjá vegu:

Arfleifð

Arfleifð Felið í sér að búa til foreldurklas og undirklasa (þ.e. erfa frá foreldurklasnum). Undirklasar fá virkni foreldurklasins og gera þér kleift að breyta henni og bæta við nýrri virkni.

Dæmi:

class Document
  attr_reader :name
end

class PDFDocument < Document
  def extension
    :pdf
  end
end

class ODTDocument < Document
  def extension
    :odt
  end
end

Einingar

Modúl í Rúbín Eiga margvíslega notkun. Ein þeirra er mixins (lestu meira um mixins í Endanleg sundurliðun: Ruby vs. Python). Mixins í Ruby má nota á svipaðan hátt og viðmót í öðrum forritunarmál (t.d. í Java), til dæmis geturðu skilgreint í þeim aðferðir sem sameiginlegar eru fyrir hluti og sem innihalda ákveðinn mixin. Það er gott vinnubrögð að setja eingöngu lestraraðferðir í einingar, þ.e. aðferðir sem breyta ekki ástandi þessa hlutar.

Dæmi:

module Taxable
  def tax

 price * 0.23
  end
end

class Car
  include Taxable
 attr_reader :price
end

class Book
  include Taxable

 attr_reader :price
end

Öndartýpu

Þetta er ein af lykilatriðum dýnamískra forritunarmála. Nafnið kemur frá hinum fræga prófi: ef það lítur út eins og önd, syndir eins og önd og kvakar eins og önd, þá er það líklega önd. forritari Þarf ekki að hafa áhuga á því hvaða flokki gefið hlutinn tilheyrir. Það sem skiptir máli eru aðferðirnar sem hægt er að kalla á þennan hlut.

Með því að nota klasana sem skilgreindir eru í dæminu hér að ofan:

class Car
  attr_reader :price

 def initialize(price)
    @price = price
   end
end

class Book
  attr_reader :price

 def initialize(price)
    @price = price
  end
end

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

[car, book].map(&:price)

GrapQL

GraphQL er tiltölulega nýtt fyrirspurnarmál fyrir API. Kostir þess felast í því að það hefur mjög einfalda málfræði og auk þess ákveður viðskiptavinurinn nákvæmlega hvað hann vill fá, þannig að hver viðskiptavinur fær nákvæmlega það sem hann vill og ekkert annað.

Sýnifyrirspurn í GraphQL:

{
  allUsers {
 users {
 id
 login
 email

 }
 }
   }

Dæmisvar svars:

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

Þetta er líklega allt sem við þurfum að vita um þessar mundir. Svo skulum við koma að kjarna málsins.

Kynning á vandamálinu

Til að skilja vandamálið og lausnina sem best skulum við búa til dæmi. Gott væri ef dæmið væri bæði frumlegt og nokkuð jarðtengt. Eitt sem hver og einn okkur getur rekist á einhvern daginn. Hvað með… dýr? Já! Frábær hugmynd!

Ruby og GraphQL margbreytileiki - dýr

Segjum að við höfum bakendaforrit skrifað í Ruby on Rails. Það er þegar aðlagað til að takast á við ofangreinda áætlun. Látum okkur einnig gera ráð fyrir að við höfum þegar GraphQL stillt. Við viljum gera viðskiptavininum kleift að senda fyrirspurn innan eftirfarandi uppbyggingar:

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

Hvað eigi að setja í staðinn fyrir þrjá punkta til að fá fram vantar upplýsingar – það komumst við að síðar.

Innleiðing

Hér að neðan mun ég kynna skrefin sem þarf til að ná markmiðinu.

Bæta fyrirspurn við QueryType

Í fyrsta lagi þarftu að skilgreina nákvæmlega hvað fyrirspurnin allZoos þýðir. Til þess þurfum við að opna skrána.app/graphql/types/query_type.rb og skilgreina fyrirspurnina:

   Gerðir eininga
 class QueryType < Types::BaseObject
 field :all_zoos, [Types::ZooType], null: false

 def all_zoos
 Zoo.all
 end
    end
 end

Fyrirspurnin er þegar skilgreind. Nú er kominn tími til að skilgreina skilartegundirnar.

Skilgreining gerða

Fyrsta tegundin sem þarf verður ZooType. Skulum skilgreina hana í skránni. app/graphql/types/ zoo_type.rb:

Gerðir eininga
  class ZooType < Types::BaseObject
    field :name, String, null: false
    field :city, String, null: false
    field :animals, [Types::AnimalType], null: false
  end
end

Nú er kominn tími til að skilgreina gerðina AnimalType:

module Types
  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

Hvað sjáum við í kóði ofar?

  1. AnimalType erfðar frá Gerðir::Grunnsamband.
  2. Við verðum að telja upp allar tegundir sem geta myndað tiltekið samband.
    3. Við skrifum yfir fallið leysir sjálfan sig sem hlut í samhengi,sem verður að skila tegund tiltekins hlutar.

Næsta skref er að skilgreina tegundir dýra. Hins vegar vitum við að sumir eiginleikar eru sameiginlegir öllum dýrum. Skulum bæta þeim við í gerðina AnimalInterface:

Gerðir módula
  module AnimalInterface
    include Types::BaseInterface

 field :name, String, null: false
    field :age, Integer, null: false
  end
end

Með þessu viðmóti getum við haldið áfram að skilgreina tegundir einstakra dýra:

module Types
  class ElephantType < Types::BaseObject
    implements Types::AnimalInterface

 field :trunk_length, Float, null: false
  end
end

module Types
  class CatType < Types::BaseObject
   implements Types::AnimalInterface

   field :hair_type, String, null: false
  end
end

module Types
  class DogType < Types::BaseObject
    implements Types::AnimalInterface

 field :breed, String, null: false
  end
end

Þetta er það! Tilbúið! Ein síðasta spurning: hvernig getum við nýtt það sem við höfum gert frá hlið viðskiptavinarins?

Að byggja fyrirspurnina

{
 allZoos : {
   zoo: {
 name
 city
 animals: {
 __typename

 ... on ElephantType {
 name
 age
 trunkLength
 }

         ... á CatType {
 nafn
 aldur
 hárgerð
 }
 ... á DogType {
 nafn
 aldur
 tegund
 }
 }
 }

Við getum notað viðbótar __typename-reiti hér, sem skilar nákvæmri tegund tiltekins þáttar (t.d. CatType). Hvernig myndi sýnissvar líta út?

{
  "allZoos": [

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

Greining

Einn ókostur þessarar nálgunar er augljós. Í fyrirspurninni verðum við að slá inn nafn og aldur í hverri tegund, þrátt fyrir að við vitum að öll dýrin hafi þessi reiti. Þetta er ekki vandamál þegar safnið inniheldur algjörlega ólík fyrirbæri. Í þessu tilfelli deila dýrin hins vegar nánast öllum reitum. Er hægt að bæta þetta einhvern veginn?

Auðvitað! Við gerum fyrstu breytinguna í skránni. app/graphql/types/zoo_type.rb:

Gerðir eininga
  class ZooType < Types::BaseObject
    field :name, String, null: false
    field :city, String, null: false
    field :animals, [Types::AnimalInterface], null: false
  end
end

Við þurfum ekki lengur þá sambandsaðgerð sem við höfum áður skilgreint. Við breytum Gerðir::Dýrategund til Gerðir::Dýraviðmót.

Næsta skref er að bæta við falli sem skilar tegund frá Gerðir :: Dýraviðmót og bæta einnig við lista yfir orphan_types, þ.e. gerðir sem aldrei eru notaðar beint:

module Types
  module AnimalInterface
    include Types::BaseInterface

   field :name, String, null: false
   field :age, Integer, 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

Þökk sé þessari einföldu aðferð hefur fyrirspurnin minna flókna mynd:

{
  allZoos : {
   zoo: {
 name
 city
 animals: {
 __typename
 name
 age

 ... on ElephantType {
 trunkLength

 }
 ... on CatType {
 hairType

       }
 ... á Hundategund {
 tegund

 }
 }
    }
  }
}

Yfirlit

GraphQL er virkilega frábær lausn. Ef þú þekkir hana ekki enn, prófaðu hana. Treystu mér, það er þess virði. Hún leysir frábærlega vandamál sem koma upp, til dæmis í REST-API-um. Eins og ég sýndi hér að ofan, fjölbreytileiki er ekki raunveruleg hindrun fyrir það. Ég kynnti tvær aðferðir til að takast á við það.
Áminning:

  • Ef þú vinnur með lista yfir hluti sem deila sameiginlegum undirstöðu eða sameiginlegu viðmóti – notaðu viðmótin.,
  • Ef þú vinnur með lista yfir hluti með annan uppbyggingu, notaðu annað viðmót – notaðu union.

Lesa meira

GraphQL Ruby. Hvernig er frammistaðan?

Lestar og önnur samgöngutæki

Rails-þróun með tmux, vim, fzf og ripgrep

Tengdar greinar

Myndskreyting af heilbrigðisforriti fyrir snjallsíma með hjartatákni og hækkandi heilsufarsgrafík, merkt með The Codest-merkinu, sem táknar stafræna heilsu og HealthTech-lausnir.
Hugbúnaðarþróun

Heilbrigðis-hugbúnaður: gerðir og notkunartilvik

Tólin sem heilbrigðisstofnanir treysta á í dag líta ekkert út eins og pappírsskjöl frá fyrri áratugum. Heilbrigðisforrit styðja nú heilbrigðiskerfi, sjúklingameðferð og nútímalega heilbrigðisþjónustu á klínískum og...

THECODEST
Yfirlitsmynd sem sýnir hnignandi súlurit með uppstrekktri ör og gullmynt sem táknar kostnaðarhagkvæmni eða sparnað. The Codest-merkið birtist í efra vinstra horni með slagorðinu "In Code We Trust" á ljósgráum bakgrunni.
Hugbúnaðarþróun

Hvernig á að stækka þróunarteymið án þess að fórna gæðum vörunnar

Ertu að stækka þróunarteymið þitt? Lærðu hvernig á að vaxa án þess að fórna gæðum vörunnar. Þessi leiðarvísir fjallar um merki um að kominn sé tími til að stækka, uppbyggingu teymisins, ráðningar, forystu og verkfæri—og hvernig teymið getur...

THECODEST
Hugbúnaðarþróun

Búðu til vefumsóknir sem þola framtíðina: innsýn frá sérfræðiteymi The Codest

Uppgötvaðu hvernig The Codest skarar fram úr við að búa til stigstækar, gagnvirkar vefumsóknir með nýjustu tækni, sem bjóða upp á hnökralausa notendaupplifun á öllum kerfum. Lærðu hvernig sérfræðiþekking okkar knýr fram stafræna umbreytingu og viðskipti...

THECODEST
Hugbúnaðarþróun

Topp 10 hugbúnaðarþróunarfyrirtæki í Lettlandi

Kynntu þér fremstu hugbúnaðarþróunarfyrirtæki Lettlands og nýstárlegar lausnir þeirra í nýjustu grein okkar. Uppgötvaðu hvernig þessir tækniforingjar geta hjálpað til við að efla fyrirtækið þitt.

thecodest
Lausnir fyrir fyrirtæki og vaxtarfyrirtæki

Grunnatriði í Java hugbúnaðarþróun: Leiðarvísir að árangursríkri útvistun

Kannaðu þessa ómissandi leiðbeiningu um árangursríka outsourcing Java hugbúnaðarþróun til að auka skilvirkni, afla aðgangs að sérfræðiþekkingu og tryggja árangur verkefna með The Codest.

thecodest

Gerðu þig áskrifanda að þekkingargrunni okkar og vertu upplýstur um sérfræðiþekkingu upplýsingatæknigeirans.

    Um okkur

    The Codest – Alþjóðlegt hugbúnaðarþróunarfyrirtæki með tæknimiðstöðvar í Póllandi.

    Bretland - Höfuðstöðvar

    • Skrifstofa 303B, 182-184 High Street North E6 2JA
      Lundúnir, England

    Pólland - staðbundin tæknimiðstöðvar

    • Fabryczna skrifstofugarður, Aleja
      Herbergi 18, 31-564 Kraków
    • Brain Embassy, Konstruktorska
      11, 02-673 Varsjá, Pólland

    The Codest

    • Heim
    • Um okkur
    • Þjónusta
    • Case Studies
    • Vitið hvernig
    • Starfsferilmöguleikar
    • Orðabók

    Þjónusta

    • Það er ráðgjafi
    • Hugbúnaðarþróun
    • Bakendaþróun
    • Framhliðþróun
    • Staff Augmentation
    • Bakhliðaráþróunaraðilar
    • Skýjaverkfræðingar
    • Gagnaverkfræðingar
    • Annað
    • Gæðatryggingartæknimenn

    Auðlindir

    • Staðreyndir og goðsagnir um samstarf við utanaðkomandi hugbúnaðarþróunaraðila
    • Frá Bandaríkjunum til Evrópu: Af hverju ákveða bandarísk sprotafyrirtæki að flytja til Evrópu?
    • Samanburður á tæknifjarkerfisþróunarmiðstöðvum: Tech Offshore Europe (Pólland), ASEAN (Filippseyjar), Eurasia (Tyrkland)
    • Hvert eru helstu áskoranir CTO-a og CIO-a?
    • The Codest
    • The Codest
    • The Codest
    • Privacy policy
    • Website terms of use

    Höfundarréttur © 2026 af The Codest. Öll réttindi áskilin.

    is_ISIcelandic
    en_USEnglish de_DEGerman sv_SESwedish da_DKDanish nb_NONorwegian fiFinnish fr_FRFrench pl_PLPolish arArabic it_ITItalian es_ESSpanish nl_NLDutch etEstonian elGreek pt_PTPortuguese cs_CZCzech lvLatvian lt_LTLithuanian is_ISIcelandic