คุณอาจเคยได้ยินนักพัฒนาร้องสรรเสริญความมหัศจรรย์ของ 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 เราจะอยู่ที่บาร์ขายสินค้า