Computer >> คอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Ruby

บทนำเกี่ยวกับ GraphQL ด้วย Ruby

คุณอาจเคยได้ยินนักพัฒนาร้องสรรเสริญความมหัศจรรย์ของ GraphQL ในชุดนี้ เราชอบที่จะเรียนรู้เทคโนโลยีโดยใช้เทคโนโลยีเหล่านี้ และบทความนี้จะกล่าวถึงตัวอย่างแอปพลิเคชันที่ใช้ GraphQL

GraphQL คืออะไร

GraphQL เป็นภาษาคิวรีและรันไทม์ที่สามารถใช้สร้าง API ได้ มีตำแหน่งที่คล้ายกันในกองการพัฒนาเป็น REST API แต่มีความยืดหยุ่นมากกว่า GraphQL ต่างจาก REST ตรงที่อนุญาตให้ลูกค้าระบุรูปแบบการตอบสนองและเนื้อหา เช่นเดียวกับ SQL SELECT คำสั่งอนุญาตให้ระบุผลลัพธ์การสืบค้น GraphQL อนุญาตให้ระบุโครงสร้างข้อมูล JSON ที่ส่งคืน หลังจากการเปรียบเทียบ SQL แล้ว GraphQL ไม่ได้จัดเตรียม WHERE อนุประโยคแต่ระบุฟิลด์บนออบเจกต์ของแอปพลิเคชันที่ควรให้ข้อมูลสำหรับการตอบกลับ

GraphQL ตามชื่อที่แนะนำ โมเดล APIs ราวกับว่าแอปพลิเคชันเป็นกราฟของข้อมูล แม้ว่าคำอธิบายนี้อาจไม่ใช่วิธีที่คุณดูแอปพลิเคชันของคุณ แต่เป็นแบบจำลองที่ใช้ในระบบส่วนใหญ่ ข้อมูลที่สามารถแสดงโดย JSON เป็นกราฟ เนื่องจาก JSON เป็นเพียงกราฟกำกับ การนึกถึงแอปพลิเคชันในการนำเสนอโมเดลกราฟผ่าน API จะทำให้ GraphQL เข้าใจง่ายขึ้นมาก

การใช้ GraphQL ในแอปพลิเคชัน

ตอนนี้เราได้อธิบาย GraphQL ในแบบนามธรรมแล้ว มาลงที่การสร้างแอปพลิเคชันที่ใช้ GraphQL โดยเริ่มจากคำจำกัดความของตัวแบบข้อมูลหรือกราฟ ปีที่แล้วฉันเลือกงานอดิเรกใหม่ ฉันกำลังเรียนรู้ที่จะเล่นเบสไฟฟ้าแบบไฟฟ้าและเรียนรู้เกี่ยวกับดนตรีโดยทั่วไป ดังนั้นจึงนึกถึงตัวอย่างที่เกี่ยวข้องกับดนตรีเมื่อใช้แอปสาธิต

ประเภทวัตถุในตัวอย่างคือ ศิลปิน และ เพลง . ศิลปิน มี เพลง . หลายเพลง และ เพลง มีความเกี่ยวข้องกับ ศิลปิน . วัตถุแต่ละประเภทมีคุณสมบัติเช่น name .

กำหนด API

GraphQL ใช้ SDL (Schema Definition Language) ซึ่งบางครั้งเรียกว่า "type system definition language" ในข้อกำหนด GraphQL ในทางทฤษฎีแล้วประเภท GraphQL สามารถกำหนดในภาษาใดก็ได้ แต่ภาษาที่ไม่เชื่อเรื่องพระเจ้าที่พบบ่อยที่สุดคือ SDL ลองใช้ SDL เพื่อกำหนด API

type Artist {
  name: String!
  songs: [Song]
  origin: [String]
}

type Song {
  name: String!
  artist: Artist
  duration: Int
  release: String
}

ศิลปิน มี name นั่นคือ String . เครื่องหมายอัศเจรีย์หมายความว่าฟิลด์ non-null . songs เป็นอาร์เรย์ของ เพลง วัตถุ และ origin ซึ่งเป็น String อาร์เรย์ เพลง คล้ายกัน แต่มีหนึ่งฟิลด์คี่ release ฟิลด์ควรเป็นประเภทเวลาหรือวันที่ แต่ GraphQL ไม่มีประเภทนั้นกำหนดเป็นประเภทหลัก สำหรับการพกพาที่สมบูรณ์ระหว่างการใช้งาน GraphQL ต่างๆ String ถูกนำมาใช้. การใช้งาน GraphQL ที่เราจะใช้มี Time พิมพ์เพิ่มดังนั้นขอเปลี่ยน เพลง คำจำกัดความเพื่อให้ release ฟิลด์คือ Time พิมพ์. ค่าที่ส่งคืนจะเป็น String แต่โดยการตั้งค่าประเภทเป็น Time เราจัดทำเอกสาร API ให้แม่นยำยิ่งขึ้น

  release: Time

ขั้นตอนสุดท้ายคือการอธิบายวิธีรับวัตถุหนึ่งชิ้นขึ้นไป นี่เรียกว่ารูทหรือสำหรับการสืบค้นรูทของเคียวรี รูทของเราจะมีเพียงหนึ่งฟิลด์หรือเมธอดที่เรียกว่า artist และจะต้องใช้ศิลปิน name .

type Query {
  artist(name: String!): Artist
}

การเขียนใบสมัคร

มาดูกันว่าเราจะใช้สิ่งนี้ในแอปพลิเคชันอย่างไร มีการใช้งานเซิร์ฟเวอร์ GraphQL สำหรับ Ruby หลายอย่าง วิธีการบางอย่างต้องการ SDL ด้านบนเพื่อแปลเป็น Ruby ที่เทียบเท่า Agoo ซึ่งเป็นเซิร์ฟเวอร์ HTTP ที่ฉันสร้างขึ้น ใช้คำจำกัดความ SDL ตามที่เป็นอยู่ และรหัส Ruby คือ vanilla Ruby ธรรมดา นั่นคือสิ่งที่เราจะใช้

โปรดทราบว่าคลาส Ruby ตรงกับประเภท GraphQL การให้ชื่อคลาส Ruby ตรงกับชื่อประเภท GraphQL เราจะไม่เพิ่มความซับซ้อนที่ไม่จำเป็น

class Artist
  attr_reader :name
  attr_reader :songs
  attr_reader :origin
 
  def initialize(name, origin)
    @name = name
    @songs = []
    @origin = origin
  end
 
  # Only used by the Song to add itself to the artist.
  def add_song(song)
    @songs << song
  end
end
 
class Song
  attr_reader :name     # string
  attr_reader :artist   # reference
  attr_reader :duration # integer
  attr_reader :release  # time
 
  def initialize(name, artist, duration, release)
    @name = name
    @artist = artist
    @duration = duration
    @release = release
    artist.add_song(self)
  end
end

เมธอดตรงกับฟิลด์ในคลาส Ruby โปรดทราบว่าวิธีการไม่มีอาร์กิวเมนต์หรือ args={} . นี่คือสิ่งที่ GraphQL API คาดหวังและการใช้งานของเราที่นี่ก็เป็นไปตามความเหมาะสม initialize เมธอดที่ใช้ในการตั้งค่าข้อมูลสำหรับตัวอย่าง เราจะเห็นในไม่ช้านี้

ต้องกำหนดคลาสรูทของเคียวรีด้วย หมายเหตุ artist เมธอดที่ตรงกับ SDL Query ประเภทราก attr_reader สำหรับ artist ถูกเพิ่มเข้ามาด้วย ที่จะเปิดเผยต่อ API เพียงแค่เพิ่มฟิลด์นั้นใน Query พิมพ์เอกสาร SDL

class Query
  attr_reader :artists
 
  def initialize(artists)
    @artists = artists
  end
 
  def artist(args={})
    @artists[args['name']]
  end
end

รูท GraphQL (เพื่อไม่ให้สับสนกับรูทของเคียวรี) อยู่เหนือรูทของเคียวรี GraphQL กำหนดให้มีตัวเลือกสามฟิลด์ คลาส Ruby ในกรณีนี้ ใช้กับ query สนาม. เครื่องมือเริ่มต้นจะโหลดข้อมูลสำหรับวงดนตรีอินดี้จากนิวซีแลนด์ที่ฉันชอบฟัง

class Schema
  attr_reader :query
  attr_reader :mutation
  attr_reader :subscription
 
  def initialize()
    # Set up some data for testing.
    artist = Artist.new('Fazerdaze', ['Morningside', 'Auckland', 'New Zealand'])
    Song.new('Jennifer', artist, 240, Time.utc(2017, 5, 5))
    Song.new('Lucky Girl', artist, 170, Time.utc(2017, 5, 5))
    Song.new('Friends', artist, 194, Time.utc(2017, 5, 5))
    Song.new('Reel', artist, 193, Time.utc(2015, 11, 2))
    @artists = {artist.name => artist}
 
    @query = Query.new(@artists)
  end
end

การตั้งค่าขั้นสุดท้ายเป็นการนำไปปฏิบัติโดยเฉพาะ ที่นี่ เซิร์ฟเวอร์เริ่มต้นเพื่อรวมตัวจัดการสำหรับ /graphql เส้นทางคำขอ HTTP แล้วจึงเริ่มต้น

Agoo::Server.init(6464, 'root', thread_count: 1, graphql: '/graphql')
Agoo::Server.start()

การใช้งาน GraphQL จะได้รับการกำหนดค่าด้วย SDL ที่กำหนดไว้ก่อนหน้านี้ ($songs_sdl ) จากนั้นแอปพลิเคชันจะเข้าสู่โหมดสลีปในขณะที่เซิร์ฟเวอร์ประมวลผลคำขอ

Agoo::GraphQL.schema(Schema.new) {
  Agoo::GraphQL.load($songs_sdl)
}
sleep

รหัสสำหรับตัวอย่างนี้มีอยู่ใน GitHub

การใช้ API

หากต้องการทดสอบ API คุณสามารถใช้เว็บเบราว์เซอร์ บุรุษไปรษณีย์ หรือ curl .

แบบสอบถาม GraphQL ที่จะลองมีลักษณะดังนี้:

{
  artist(name:"Fazerdaze") {
    name
    songs{
      name
      duration
    }
  }
}

แบบสอบถามขอศิลปิน ชื่อ Fazerdaze และส่งคืน name และ songs ในเอกสาร JSON สำหรับแต่ละ เพลง name และ duration ของ เพลง ถูกส่งกลับในวัตถุ JSON ผลลัพธ์ควรมีลักษณะดังนี้

{
  "data": {
    "artist": {
      "name": "Fazerdaze",
      "songs": [
        {
          "name": "Jennifer",
          "duration": 240
        },
        {
          "name": "Lucky Girl",
          "duration": 170
        },
        {
          "name": "Friends",
          "duration": 194
        },
        {
          "name": "Reel",
          "duration": 193
        }
      ]
    }
  }
}

หลังจากกำจัดช่องว่างทางเลือกในแบบสอบถาม HTTP GET ที่สร้างด้วย curl ควรส่งคืนเนื้อหานั้น

curl -w "\n" 'localhost:6464/graphql?query=\{artist(name:"Fazerdaze")\{name,songs\{name,duration\}\}\}&indent=2'

ลองเปลี่ยนข้อความค้นหาและแทนที่ duration กับ release และสังเกตการแปลง Ruby Time เป็นสตริง JSON

ส่งท้ายเพลง

เราสนุกกับการเล่นกับ GraphQL และเราหวังว่าคุณจะแท็กและเรียนรู้บางอย่างระหว่างทาง ขอบคุณ คุณผู้ชมที่ดี หากคุณต้องการพูดคุยเพิ่มเติมกับ Ruby เราจะอยู่ที่บาร์ขายสินค้า